更新时间:2022-10-07 22:49:15
到目前为止,已经简单学习了Spring的Core模块….于是我们就开启了Spring的AOP模块了…在讲解AOP模块之前,首先我们来讲解一下cglib代理、以及怎么手动实现AOP编程
在讲解cglib之前,首先我们来回顾一下静态代理和动态代理….我之前就写过了静态代理、动态代理的博文:http://blog.csdn.net/hon_3y/article/details/70655966
由于静态代理需要实现目标对象的相同接口,那么可能会导致代理类会非常非常多….不好维护---->因此出现了动态代理
动态代理也有个约束:目标对象一定是要有接口的,没有接口就不能实现动态代理…..----->因此出现了cglib代理
cglib代理也叫子类代理,从内存中构建出一个子类来扩展目标对象的功能!
接下来我们就讲讲怎么写cglib代理:
//需要实现MethodInterceptor接口 public class ProxyFactory implements MethodInterceptor{ // 维护目标对象 private Object target; public ProxyFactory(Object target){ this.target = target; } // 给目标对象创建代理对象 public Object getProxyInstance(){ //1. 工具类 Enhancer en = new Enhancer(); //2. 设置父类 en.setSuperclass(target.getClass()); //3. 设置回调函数 en.setCallback(this); //4. 创建子类(代理对象) return en.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("开始事务....."); // 执行目标对象的方法 Object returnValue = method.invoke(target, args); System.out.println("提交事务....."); return returnValue; } }
public class App { public static void main(String[] args) { UserDao userDao = new UserDao(); UserDao factory = (UserDao) new ProxyFactory(userDao).getProxyInstance(); factory.save(); } }
使用cglib就是为了弥补动态代理的不足【动态代理的目标对象一定要实现接口】
AOP 面向切面的编程:
下面我们来看一段代码:
// 保存一个用户 public void add(User user) { Session session = null; Transaction trans = null; try { session = HibernateSessionFactoryUtils.getSession(); // 【关注点代码】 trans = session.beginTransaction(); // 【关注点代码】 session.save(user); // 核心业务代码 trans.commit(); //…【关注点代码】 } catch (Exception e) { e.printStackTrace(); if(trans != null){ trans.rollback(); //..【关注点代码】 } } finally{ HibernateSessionFactoryUtils.closeSession(session); ////..【关注点代码】 } }
public interface IUser { void save(); }
我们一步一步来分析,首先我们的UserDao有一个save()方法,每次都要开启事务和关闭事务
//@Component -->任何地方都能用这个 @Repository //-->这个在Dao层中使用 public class UserDao { public void save() { System.out.println("开始事务"); System.out.println("DB:保存用户"); System.out.println("关闭事务"); } }
//@Component -->任何地方都能用这个 @Repository //-->这个在Dao层中使用 public class UserDao { public void save() { begin(); System.out.println("DB:保存用户"); close(); } public void begin() { System.out.println("开始事务"); } public void close() { System.out.println("关闭事务"); } }
public class AOP { public void begin() { System.out.println("开始事务"); } public void close() { System.out.println("关闭事务"); } }
@Repository //-->这个在Dao层中使用 public class UserDao { AOP aop; public void save() { aop.begin(); System.out.println("DB:保存用户"); aop.close(); } }
public class ProxyFactory { //维护目标对象 private static Object target; //维护关键点代码的类 private static AOP aop; public static Object getProxyInstance(Object target_, AOP aop_) { //目标对象和关键点代码的类都是通过外界传递进来 target = target_; aop = aop_; return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { aop.begin(); Object returnValue = method.invoke(target, args); aop.close(); return returnValue; } } ); } }