代理:比如A类需要实现查询功能,就只做查询,而开启事务交由B类处理(相当于某些事情交于其他人帮你做)。
代理类:目标被添加增强代码后,生成的新类就是代理类。
被代理类:目标类,需要被添加增强代码的类。
AOP的实现主要依赖于动态代理。
实现动态代理的两种方式:
1.JavaSE的动态代理(通过JDK):
要求:
(1)被增强对象必须实现接口;
(2)代理类必须实现java.lang.reflect.InvocationHandler接口;
(3)通过Proxy类的newProxyInstance()方法创建代理实例。
步骤:
(1)需要创建业务类和增强类的实例
(2)构建代理容器,在构造函数中传入业务对象和增强对象ServiceInfo sInf = new ServiceImp();//创建被代理的类对象 Manager manager = new Manager();//创建增强代码类对象
(3)调用java.lang.reflect.Proxy类的静态函数newProxyInstance()创建动态代理对象,传入类加载器、业务接口、代理容器对象。InvocationHandler handler = new ProxyClass(sInf, manager);//创建代理类对象
(4)通过动态代理对象调用函数ServiceInfo service = (ServiceInfo)Proxy.newProxyInstance(sInf.getClass().getClassLoader(), sInf.getClass().getInterfaces(), handler);
对应的业务接口,业务类,增强类,代理类,测试类如下:service.add("zhangsan", 18); service.reRs(20);
ServiceInfo.java:业务接口
ServiceImp.java:业务接口实现类package service; public interface ServiceInfo { void add(String name,int age); void reRs(int id); }
Manager:增强类package service; public class ServiceImp implements ServiceInfo{ @Override public void add(String name, int age) { System.out.println("执行添加操作:"+name+" "+age); } @Override public void reRs(int id) { System.out.println("执行返回结果:"+id); } }
ProxyClass.java:代理类package service; /** * 增强类 * @author ${HLoach} * 2017年3月15日 */ public class Manager { public void beginTran(){ System.out.println("【事务管理】开始事务"); } public void commit(){ System.out.println("【事务管理】提交事务"); } public void rollback(){ System.out.println("【事务管理】事务回滚"); } }
Test1.java:测试类package service; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class ProxyClass implements InvocationHandler{ private Object object;//需要被代理的类 private Manager manager;//用于执行增强操作的类 public ProxyClass(Object object,Manager manager) { this.object = object; this.manager = manager; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //针对方法进行限制,提高AOP的灵活性 //限制只有名称以add开头的方法才能被增强 if(!method.getName().startsWith("add")){ return method.invoke(object, args);//直接调用函数 } manager.beginTran(); try { Object rs = method.invoke(object, args); manager.commit(); return rs; } catch (Exception e) { manager.rollback(); } return null; } }
执行结果如下:package service; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class Test1 { public static void main(String[] args) { ServiceInfo sInf = new ServiceImp();//创建被代理的类对象 Manager manager = new Manager();//创建增强代码类对象 InvocationHandler handler = new ProxyClass(sInf, manager);//创建代理类对象 ServiceInfo service = (ServiceInfo)Proxy.newProxyInstance(sInf.getClass().getClassLoader(), sInf.getClass().getInterfaces(), handler);//创建动态代理对象 service.add("zhangsan", 18); service.reRs(20); } }
【事务管理】开始事务
执行添加操作:zhangsan 18
【事务管理】提交事务
执行返回结果:20
2.通过cglib(code generation library,代码生成类库)实现动态代理,这时,被代理类(被增强对象)不用实现接口。
要求:
(1)代理类必须实现org.springframework.cglib.proxy.MethodInterceptor接口
步骤:
(1)创建增强对象
(2)创建cglib代理MethodInterceptor的实现类对象(代理类对象)Manager manager = new Manager();
(3)创建增强器,通过增强器设置需要被增强的类,并设置增强类回调到代理类中去使用,然后创建代理对象。MethodInterceptor interceptor = new ProxyClass(manager);
(4)通过代理对象调用函数//创建增强器 Enhancer enhancer = new Enhancer(); //设置需要被增强的类 enhancer.setSuperclass(ServiceClass.class); //设置被增强类回调到代理类中去使用 enhancer.setCallback(interceptor); //创建代理对象 ServiceClass sClass = (ServiceClass) enhancer.create();
对应增强类,代理类,测试类如下:sClass.add("lisi", 23); sClass.reRs(15);
Manager.java:增强类
ProxyClass.java:代理类package service2; /** * 增强类 * @author ${HLoach} * 2017年3月15日 */ public class Manager { public void beginTran(){ System.out.println("【事务管理】开始事务"); } public void commit(){ System.out.println("【事务管理】提交事务"); } public void rollback(){ System.out.println("【事务管理】事务回滚"); } }
package service2; import java.lang.reflect.Method; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; public class ProxyClass implements MethodInterceptor{ private Manager manager;//用于执行增强操作的类 public ProxyClass(Manager manager) { this.manager = manager; } @Override public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { if(!method.getName().startsWith("add")){ return methodProxy.invokeSuper(object, args);//直接调用函数 } manager.beginTran(); try { Object rs = methodProxy.invokeSuper(object, args);//这里的object对象是被代理类对象,
manager.commit();return rs;} catch (Exception e) {e.printStackTrace();manager.rollback();}return null;}} ServiceClass.java:被代理类//methodProxy对象存了被代理类中所有方法
package service2; public class ServiceClass{ public void add(String name, int age) { System.out.println("执行添加操作:"+name+" "+age); } public void reRs(int id) { System.out.println("执行返回结果:"+id); } }
Test2.java:测试类
执行结果:package service2; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; public class Test2 { public static void main(String[] args) { //创建增强对象 Manager manager = new Manager(); //cglib代理MethodInterceptor对象 MethodInterceptor interceptor = new ProxyClass(manager); //创建增强器 Enhancer enhancer = new Enhancer(); //设置需要被增强的类 enhancer.setSuperclass(ServiceClass.class); //设置被增强类回调到代理类中去使用 enhancer.setCallback(interceptor); //创建代理对象 ServiceClass sClass = (ServiceClass) enhancer.create(); //通过代理对象调用函数 sClass.add("lisi", 23); sClass.reRs(15); } }
【事务管理】开始事务
执行添加操作:lisi 23
【事务管理】提交事务
执行返回结果:15