1.接口有实现类(有目标方法)
package com.demo.demo; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; interface LogService{ void doSave(); } class LogServiceImpl implements LogService{//目标对象 public void doSave() { System.out.println("save Log"); } } class LogAspect{ public void before(){//Aspect(切面) System.out.println("method before"); } public void after(){ System.out.println("method after"); } } public class TestProxy01 { //在此类的对象方法中调用目标方法,添加业务扩展功能 static class ServiceHandler implements InvocationHandler{ private Object target; private LogAspect logAspect=new LogAspect(); public ServiceHandler(Object target){ this.target=target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //执行日志切面方法 logAspect.before(); //执行目标对象方法 method.invoke(target, args); //执行日志切面方法 logAspect.after(); return null; }//整合核心业务调用与扩展业务调用 } /** * 借助 JDK API(Proxy) 为目标对象创建动态代理对象 * @param target * @return */ static Object newLogServicePorxy(LogService target){ LogService logService = (LogService)Proxy.newProxyInstance( target.getClass().getClassLoader(), //loader 类的加载器 target.getClass().getInterfaces(), //interfaces 目标对象实现的接口 new ServiceHandler(target)); //h 处理器,处理目标对象和 代理对象要织入扩展功能的业务的处理器 return logService; } public static void main(String[] args) { LogService logService = (LogService) newLogServicePorxy(new LogServiceImpl()); //当调用doSave方法时,系统底层会调用Handler对象的 //invoke方法,执行核心业务与扩展业务的整合 logService.doSave(); } }
2.接口没有实现类(即没有目标方法,仿照mybatis中的dao层)
package com.demo.demo; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Map; interface FindDao{ Map<String,String> findDao(Integer i); } class DemoProxy implements InvocationHandler{ public static Object finds(Class<?> target) { Object obj = Proxy.newProxyInstance( target.getClassLoader(), new Class[]{target}, new DemoProxy()); return obj; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("do invoke!!!"); return null; } } public class TestProxy03 { public static void main(String[] args) { FindDao f=(FindDao) DemoProxy.finds(FindDao.class); f.findDao(5); } }
3.没有实现一个接口,直接就是一个类,需要使用CGLIB来做动态代理
package com.demo.demo; import java.lang.reflect.Method; import org.springframework.cglib.proxy.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodProxy; //目标对象 class HelloServiceImpl{ public void sayHello(){ System.out.println(" is ok !!! "); } } //如何借助CGLIB为如上对象创建一个代理对象 //通过代理对象扩展 如上对象的扩展功能 public class TestProxy04 { public static void main(String[] args) { //创建EnHancer对象(此对象为使用CGLIB入口对象) //要借助此对象为目标对象创建代理对象 //这里的代理对象是目标对象的一个子类类型对象 Enhancer h = new Enhancer(); //设置代理对象要继承的那个父类的类型 h.setSuperclass(HelloServiceImpl.class); //设置回调函数(当指定代理对象的方法时,会执行此Callback函数 h.setCallback(new MethodInterceptor() { public Object intercept( Object arg0,//指向代理对象 Method arg1,//目标对象的方法 Object[] arg2,//方法执行时实际参数 MethodProxy arg3//方法对象的代理 ) throws Throwable { System.out.println("before do"); Object result = arg3.invokeSuper(arg0, arg2); System.out.println("after do"); return result; } });//类似JDK动态代理的InvocationHandler Object obj = h.create(); HelloServiceImpl hs = (HelloServiceImpl) obj; hs.sayHello(); } }
总结: AOP 底层基于代理机制实现功能扩展
1.假如目标对象(被代理的对象)实现接口,则底层默认采用JDK动态代理机制为目标对象创建代理对象(目标类和代理类会实现共同接口)
2.假如目标对象(被代理对象)没有实现接口,则底层默认采用CGLIB代理机制为目标对象创建代理对象(默认创建的代理类会继承目标对象类型)