面向接口的jdk动态代理(spring默认代理)
package com.yc.advice; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Date; public class LogAdvice implements InvocationHandler { //代理模式中一定要有目标类的引用 private Object tagetObject; //注意这个就是目标类的应用 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //调用目标的相应方法 Object returnValue=method.invoke(tagetObject, args); String methodName=method.getName(); if(methodName.startsWith("add")||methodName.startsWith("del")||methodName.startsWith("update")||methodName.startsWith("modify")){ log(method,args,tagetObject); } return returnValue; } //创建一个方法来完毕创建代理对象 public Object createInstance(Object tagetObject){ this.tagetObject=tagetObject; //生成一个代理对象 //生成一个代理对象,这个代理对象使依据目标对象的接口生成的 return Proxy.newProxyInstance(tagetObject.getClass().getClassLoader(),tagetObject.getClass().getInterfaces() , this); //在client我们调用createInstance()得到一个代理对象,在调用这个代理对象的方法->它就会自己主动的回调(由于this)invoke //全部在invoke里面写入你要增强的方法 } private void log(Method method, Object[] args, Object tagetObject2){ System.out.println("********************"); System.out.println("日志检查"+new Date()); System.out.println("********************"); } }
package com.yc.advice; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //在这个类使一个且面类。完毕的功能使向目标类的目标方法增加功能(增强) public class RightAdvice implements InvocationHandler{ //代理模式中一定要有目标类的引用 private Object tagetObject; //注意这个就是目标类的应用 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName=method.getName(); if(methodName.startsWith("add")||methodName.startsWith("del")||methodName.startsWith("update")||methodName.startsWith("modify")){ check(); } //调用目标的相应方法 Object returnValue=method.invoke(tagetObject, args); return returnValue; } //创建一个方法来完毕创建代理对象 public Object createInstance(Object tagetObject){ this.tagetObject=tagetObject; //生成一个代理对象 //生成一个代理对象,这个代理对象使依据目标对象的接口生成的 return Proxy.newProxyInstance(tagetObject.getClass().getClassLoader(),tagetObject.getClass().getInterfaces() , this); //在client我们调用createInstance()得到一个代理对象,在调用这个代理对象的方法->它就会自己主动的回调(由于this)invoke //全部在invoke里面写入你要增强的方法 } private void check(){ System.out.println("********************"); System.out.println("权限检查"); System.out.println("********************"); } }
package com.yc.biz; public interface ProductBiz { public void addProduct(); public void delProduct(); public void updateProduct(); public void findProduct(); }
package com.yc.biz; //真是主题 public class ProductBizImpl implements ProductBiz { @Override public void addProduct() { System.out.println("************************"); System.out.println("加入产品"); System.out.println("*************************"); } @Override public void delProduct() { System.out.println("************************"); System.out.println("删除产品"); System.out.println("*************************"); } @Override public void updateProduct() { System.out.println("************************"); System.out.println("更新产品"); System.out.println("*************************"); } @Override public void findProduct() { System.out.println("************************"); System.out.println("查找产品"); System.out.println("*************************"); } }
package com.yc.biz; import com.yc.advice.LogAdvice; import com.yc.advice.RightAdvice; public class Test { public static void main(String[] args) { RightAdvice ra=new RightAdvice(); LogAdvice la=new LogAdvice(); ProductBiz pb=new ProductBizImpl(); ProductBiz productProxy=(ProductBiz) ra.createInstance(la.createInstance(pb)); productProxy.addProduct(); } }
另一种是面向继承的cglib动态代理
首先要导入一个包cglib-nodep-2.1_3.jar
还是上面的样例,可是差别在于增强类的写法上有一点不同,大家看一下
package com.yc.advice; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Date; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class LogAdvice implements MethodInterceptor { //代理模式中一定要有目标类的引用 private Object tagetObject; //注意这个就是目标类的应用 //创建一个方法来完毕创建代理对象 public Object createInstance(Object tagetObject){ this.tagetObject=tagetObject; Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(tagetObject.getClass()); enhancer.setCallback(this); return enhancer.create(); } private void log(Method method, Object[] args, Object tagetObject2){ System.out.println("********************"); System.out.println("日志检查"+new Date()); System.out.println("********************"); } @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy arg3) throws Throwable { //调用目标的相应方法 Object returnValue=method.invoke(tagetObject, args); String methodName=method.getName(); if(methodName.startsWith("add")||methodName.startsWith("del")||methodName.startsWith("update")||methodName.startsWith("modify")){ log(method,args,tagetObject); } return returnValue; } }
package com.yc.advice; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; //在这个类使一个且面类,完毕的功能使向目标类的目标方法增加功能(增强) public class RightAdvice implements MethodInterceptor{ //代理模式中一定要有目标类的引用 private Object tagetObject; //注意这个就是目标类的应用 //创建一个方法来完毕创建代理对象 public Object createInstance(Object tagetObject){ this.tagetObject=tagetObject; Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(tagetObject.getClass().getSuperclass()); enhancer.setCallback(this); return enhancer.create(); } private void check(){ System.out.println("********************"); System.out.println("权限检查"); System.out.println("********************"); } @Override public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable { String methodName=method.getName(); if(methodName.startsWith("add")||methodName.startsWith("del")||methodName.startsWith("update")||methodName.startsWith("modify")){ check(); } //调用目标的相应方法 Object returnValue=method.invoke(tagetObject, args); return returnValue; } }
想了想静态代理也贴上来了。我认为静态代理便于理解,更直观
和上面不同的是将增强类LogAdvice和RightAdvice两个类替换成了ProductBIzLogProxy和ProductBIzRightProxy两个类
package com.yc.biz; import java.util.Date; public class ProductBIzLogProxy implements ProductBiz{ private ProductBiz productBiz; public ProductBIzLogProxy(ProductBiz productBiz) { // TODO Auto-generated constructor stub this.productBiz=productBiz; } @Override public void addProduct() { // TODO Auto-generated method stub this.productBiz.addProduct(); //后置增强 log(); } private void log(){ System.out.println("%%%%%%%%%%%%"); System.out.println("操作时间"+new Date()); System.out.println("%%%%%%%%%%%%%"); } }
package com.yc.biz; //代理类 public class ProductBizRightProxy implements ProductBiz { private ProductBiz productBiz; public ProductBizRightProxy(ProductBiz productBiz) { // TODO Auto-generated constructor stub this.productBiz=productBiz; } @Override public void addProduct() { //增加检查权限的功能 check(); this.productBiz.addProduct(); } //增强的功能 private void check(){ System.out.println("=========================="); System.out.println("检查权限......."); System.out.println("=========================="); } }
測试类改为:
package com.yc.biz; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub // ProductBiz pb=new ProductBizRightProxy(new ProductBizImpl()); // pb.addProduct(); ProductBiz pb=new ProductBizRightProxy(new ProductBIzLogProxy(new ProductBizImpl())); pb.addProduct(); } }