为了搞清楚spring AOP的代理原理,在网上找了一些资料学习,总结如下:
代理模式:可以在不修改目标对象功能的前提下,对目标进行功能扩展。
1,静态代理:需要代理对象和被代理对象实现相同接口或者继承相同的父类
静态代理一个很大的问题是,一旦目标对象实现的接口或者继承的父类新增了方法,那么代理对象和目标对象都需要进行修改
接口:
package com.wh.www.service;
public interface DynamicProxyInterface {
String sayHello(String name);
}
目标对象:
package com.wh.www.service.impl;
import com.wh.www.service.DynamicProxyInterface;
/**
*
* @author itw_hubo
*
*/
public class DynamicProxyService implements DynamicProxyInterface {
public String sayHello(String name) {
return "Hello " + name;
}
}
代理对象factory:
package com.wh.www.service.impl;
import com.wh.www.service.DynamicProxyInterface;
public class StaticProxyService implements DynamicProxyInterface {
private DynamicProxyInterface dynamicProxyService;
public StaticProxyService(DynamicProxyInterface dynamicProxyService) {
this.dynamicProxyService = dynamicProxyService;
}
public String sayHello(String name) {
System.out.println("start Static Proxy demo");
String obj = dynamicProxyService.sayHello(name);
System.out.println("end Static Proxy demo");
return obj;
}
}
测试类:
package com.wh.www.service.impl;
public class StaticProxyDemo {
public static void main(String[] args) {
DynamicProxyService service = new DynamicProxyService();
StaticProxyService staticproxy = new StaticProxyService(service);
System.out.println(staticproxy.sayHello("hubo"));
}
}
2,动态代理:利用JDK的API,动态的在内存中构建代理对象,也叫JDK代理,接口代理
要求目标对象必须实现接口,不然不能动态代理
使用上面静态代理中的接口和目标对象
动态代理factory:
package com.wh.www.service.impl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
*
* @author itw_hubo
*
*/
public class DynamicProxyFactory {
private Object proxyService;
public DynamicProxyFactory(Object proxyService) {
this.proxyService = proxyService;
}
public Object getProxyIntance() {
return Proxy.newProxyInstance(proxyService.getClass().getClassLoader(),
proxyService.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
System.out.println("start Dynamic Proxy demo");
Object rtnValue = arg1.invoke(proxyService, arg2);
System.out.println("end Dynamic Proxy demo");
return rtnValue;
}
});
}
}
测试类:
package com.wh.www.service.impl;
import com.wh.www.service.DynamicProxyInterface;
/**
* JDK的API代理
* @author itw_hubo
*
*/
public class DynamicProxyDemo {
public static void main(String[] args) {
DynamicProxyInterface proxy = new DynamicProxyService();
DynamicProxyFactory factory = new DynamicProxyFactory(proxy);//初始化代理对象
DynamicProxyInterface inter = (DynamicProxyInterface)factory.getProxyIntance();//获取代理对象
System.out.println(inter.sayHello("hubo"));
}
}
3,cglib代理,以目标对象子类的方式实现代理,因为使用的时子类,所以有几个注意点:
a,目标对象不能为final,否则报错
Exception in thread "main" java.lang.IllegalArgumentException: Cannot subclass final class com.wh.www.service.impl.CglibProxyService
b,目标对象的方法如果是final或者static,代理也不会成功,直接调用目标对象的方法,不会执行代理对象的业务方法
目标对象:
package com.wh.www.service.impl;
/**
* @author itw_hubo
*
*/
public class CglibProxyService {
public String sayHello(String name) {
return "Hello " + name;
}
}
代理factory:
package com.wh.www.service.impl;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
/**
* @author itw_hubo
*
*/
public class CglibProxyFactory implements MethodInterceptor{
//目标对象
private Object proxy;
//构造方法
public CglibProxyFactory(Object proxy) {
this.proxy = proxy;
}
//创建代理对象
public Object getProxyInstance() {
//工具类
Enhancer en = new Enhancer();
//设置父类
en.setSuperclass(proxy.getClass());
//设置回调函数
en.setCallback(this);
//创建子类代理对象
return en.create();
}
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
System.out.println("start Cglib Proxy demo");
Object rtnValue = arg1.invoke(proxy, arg2);
System.out.println("end Cglib Proxy demo");
return rtnValue;
}
}
测试类:
package com.wh.www.service.impl;
/**
*
* @author itw_hubo
*
*/
public class CglibProxyDemo {
public static void main(String[] args) {
CglibProxyService service = new CglibProxyService();
CglibProxyFactory factory = new CglibProxyFactory(service);
CglibProxyService proxy = (CglibProxyService)factory.getProxyInstance();
System.out.println(proxy.sayHello("lucy"));
}
}
以上代码都是可以直接执行,希望能够帮助你了解代理模式。
------
知识使我们快乐