Java Spring将一个类的一个方法放在另一个之前
我有一个使用SpringCore、SpringMVC和Hibernate的应用程序。 有很多DAO类在每种方法中都会获得新的Hibernate会话Java Spring将一个类的一个方法放在另一个之前,java,spring,hibernate,aop,Java,Spring,Hibernate,Aop,我有一个使用SpringCore、SpringMVC和Hibernate的应用程序。 有很多DAO类在每种方法中都会获得新的Hibernate会话 @Autowired private SessionFactory sessionFactory; private Session session; private void createSession() { session = sessionFactory.openSession(); } @Override publi
@Autowired
private SessionFactory sessionFactory;
private Session session;
private void createSession() {
session = sessionFactory.openSession();
}
@Override
public List<User> listUsers() {
createSession();
List users;
users = session.createQuery("from User").list();
session.close();
return users;
}
除了@Bogdan所说的之外,看看
crudepository
或JpaRepository
,它将为您节省大量时间。另外,在我看来,@Aspect
类是用@Component
注释的,而不是@Configuration
,因为您仍然没有提供一个或至少更多(和更真实)的示例代码,我只能推测并提供一个示意性的答案
顺便说一句,我在这里使用的是AspectJ,而不是SpringAOP,但是在那里它应该以同样的方式工作
使示例代码编译的伪类:
包ua.com.alistratenko.dao;
公共类用户{
字符串名;
公共用户(字符串名称){
this.name=名称;
}
@凌驾
公共字符串toString(){
返回“User[name=“+name+”]”;
}
}
包ua.com.alistratenko.dao;
导入java.util.ArrayList;
导入java.util.List;
公共类查询结果{
公开名单(){
列表用户=新建ArrayList();
添加(新用户(“jane”);
添加(新用户(“joe”);
返回用户;
}
}
包ua.com.alistratenko.dao;
公开课{
公共查询Result createQuery(字符串){
返回新的QueryResult();
}
公共void close(){}
}
包ua.com.alistratenko.dao;
公共类会话工厂{
公开会话openSession(){
返回新会话();
}
}
应用程序类:
我改变了什么
- 在春季,您将使用
,而不是自己创建会话工厂。我这样做是为了能够在没有Spring的情况下运行示例代码@Autowired
- 为方面添加了一些setter/getter,以便能够访问会话工厂和会话本身
- 删除了
(代码迁移到aspect,见下文)createSession()
listUsers()中不再有杂乱无章的样板文件
- 添加了用于演示的主方法
包ua.com.alistratenko.dao;
导入java.util.List;
公共类UserDaoImp{
私有SessionFactory SessionFactory=新SessionFactory();
非公开会议;
public SessionFactory getSessionFactory(){return SessionFactory;}
公共会话getSession(){return Session;}
public void setSession(会话){this.Session=Session;}
公共列表listUsers(){
return session.createQuery(“来自用户”).list();
}
公共静态void main(字符串[]args){
新UserDaoImp().listUsers();
}
}
方面:
为了在截获的方法调用之前+之后执行某些操作,请使用@Around
package de.scrum\u master.aspect;
导入org.aspectj.lang.ProceedingJoinPoint;
导入org.aspectj.lang.annotation.Around;
导入org.aspectj.lang.annotation.Aspect;
//导入org.springframework.stereotype.Component;
导入ua.com.alistratenko.dao.UserDaoImp;
//@组成部分
@面貌
公共类DaoSessionLifeCycle{
@大约(“执行(公共*列表用户(..)&&target(dao)”)
公共对象openSession(ProceedingJoinPoint thisJoinPoint,UserDaoImp dao)抛出可丢弃的{
试一试{
System.out.println(“创建会话”);
setSession(dao.getSessionFactory().openSession());
System.out.println(“调用”+thisJoinPoint.getSignature());
返回此连接点。继续();
}
最后{
试一试{
System.out.println(“结束会议”);
dao.getSession().close();
}
捕获(例外e){}
}
}
}
控制台日志:
创建会话
调用列表ua.com.alistratenko.dao.UserDaoImp.listUsers()
闭幕会议
现在有几个悬而未决的问题:
- 您是否只想处理这一个类,或者可能处理基类的所有子类,或者处理所有DAO通用的实现接口?那么切入点看起来就不一样了
- 您是只想截取方法
还是还想截取其他方法?由于您没有显示更多的代码,除了您之外没有人知道。切入点也会根据您的答案而有所不同listUsers()
- 您真的想手动完成这些操作,还是按照其他用户的建议使用板载Spring工具来管理您的事务?我对春天一无所知,所以我不能告诉你。我只是提供了你的问题的答案,这是与方面有关的
ua.com.alistratenko.dao.UserDaoImp
,因为我只能从切入点间接推断出来?是的,Spring AOP方面需要是@组件
,而纯AspectJ方面不需要。Update:我添加了虚拟类,使示例代码在没有Spring的情况下使用纯JavaSE+AspectJ编译
@Configuration
@Aspect
public class DaoSessionLifeCycle {
@Before(value = "execution(* ua.com.alistratenko.dao.UserDaoImp.listUsers(..))")
public void openSession(JoinPoint joinPoint){
System.out.println("izi");
}
}