面向接口的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);
//在客户端我们调用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);
//在客户端我们调用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();
}
}