10.AOP原理---java动态代理
java的动态代理:动态生成一个代理类来调用被代理的对象。(个人理解)
动态代理的调用生成的对象是生成的是代理对象(userDaoProxy),而不是被代理的实现类(userDaoImpl)。
动态编译成一个代理对象的字节码,这个对象实现了和被代理类相同的接口。
内部实现原理:
java的proxy会代理出入接口的所有的方法,将接口的方法和参数会传到拦截器中的invoke方法中。
实现步骤:
1.拦截器类intercepter实现InvoctionHandler接口
2.拦截器类重写invoke方法
3.用java的Proxy的静态方法newProxyInstance(classload,interface,intercepter)
具体事例:
动态代理示例:
1 package net.battier.dao; 2 3 public interface BookFacade { 4 public void addBook(); 5 }
1 package net.battier.dao.impl; 2 3 import net.battier.dao.BookFacade; 4 5 public class BookFacadeImpl implements BookFacade { 6 7 @Override 8 public void addBook() { 9 System.out.println("增加图书方法。。。"); 10 } 11 12 }
1 BookFacadeProxy.java 2 3 package net.battier.proxy; 4 5 import java.lang.reflect.InvocationHandler; 6 import java.lang.reflect.Method; 7 import java.lang.reflect.Proxy; 8 9 /** 10 * JDK动态代理代理类 11 * 12 * @author student 13 * 14 */ 15 public class BookFacadeProxy implements InvocationHandler { 16 private Object target; 17 /** 18 * 绑定委托对象并返回一个代理类 19 * @param target 20 * @return 21 */ 22 public Object bind(Object target) { 23 this.target = target; 24 //取得代理对象 25 return Proxy.newProxyInstance(target.getClass().getClassLoader(), 26 target.getClass().getInterfaces(), this); //要绑定接口(这是一个缺陷,cglib弥补了这一缺陷) 27 } 28 29 @Override 30 /** 31 * 调用方法 32 */ 33 public Object invoke(Object proxy, Method method, Object[] args) 34 throws Throwable { 35 Object result=null; 36 System.out.println("事物开始"); 37 //执行方法 38 result=method.invoke(target, args); 39 System.out.println("事物结束"); 40 return result; 41 } 42 43 }
1 package net.battier.test; 2 3 import net.battier.dao.BookFacade; 4 import net.battier.dao.impl.BookFacadeImpl; 5 import net.battier.proxy.BookFacadeProxy; 6 7 public class TestProxy { 8 9 public static void main(String[] args) { 10 BookFacadeProxy proxy = new BookFacadeProxy(); 11 BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl()); 12 bookProxy.addBook(); 13 } 14 15 }
Cglib动态代理
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
事例:
1 package net.battier.dao; 2 3 public interface BookFacade { 4 public void addBook(); 5 }
1 package net.battier.dao.impl; 2 3 /** 4 * 这个是没有实现接口的实现类 5 * 6 * @author student 7 * 8 */ 9 public class BookFacadeImpl1 { 10 public void addBook() { 11 System.out.println("增加图书的普通方法..."); 12 } 13 }
1 package net.battier.proxy; 2 3 import java.lang.reflect.Method; 4 5 import net.sf.cglib.proxy.Enhancer; 6 import net.sf.cglib.proxy.MethodInterceptor; 7 import net.sf.cglib.proxy.MethodProxy; 8 9 /** 10 * 使用cglib动态代理 11 * 12 * @author student 13 * 14 */ 15 public class BookFacadeCglib implements MethodInterceptor { 16 private Object target; 17 18 /** 19 * 创建代理对象 20 * 21 * @param target 22 * @return 23 */ 24 public Object getInstance(Object target) { 25 this.target = target; 26 Enhancer enhancer = new Enhancer(); 27 enhancer.setSuperclass(this.target.getClass()); 28 // 回调方法 29 enhancer.setCallback(this); 30 // 创建代理对象 31 return enhancer.create(); 32 } 33 34 @Override 35 // 回调方法 36 public Object intercept(Object obj, Method method, Object[] args, 37 MethodProxy proxy) throws Throwable { 38 System.out.println("事物开始"); 39 proxy.invokeSuper(obj, args); 40 System.out.println("事物结束"); 41 return null; 42 43 44 } 45 46 }
1 package net.battier.test; 2 3 import net.battier.dao.impl.BookFacadeImpl1; 4 import net.battier.proxy.BookFacadeCglib; 5 6 public class TestCglib { 7 8 public static void main(String[] args) { 9 BookFacadeCglib cglib=new BookFacadeCglib(); 10 BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1()); 11 bookCglib.addBook(); 12 } 13 }

浙公网安备 33010602011771号