AOP——代理技術,aop代理
一、如何理解代理技術
Proxy:不用你去做,別人代替你去處理。如Windows快捷方式,又如房屋中介
起到一個中介作用,通過代理對象,可以去掉客戶不能看到的內容和服務或者添加客戶需要的額外服務。
二、代理模式
代理模式使用代理對象完成用戶請求,屏蔽用戶對真實對象的訪問。現實世界的代理人被授權執行當事人的一些事宜,無需當事人出面,從第三方的角度看,似乎當事人並不存在,因為他只和代理人通信。
而事實上代理人是要有當事人的授權,並且在核心問題上還需要請示當事人。
在軟件設計中,使用代理模式的意圖也很多,比如因為安全原因需要屏蔽客戶端直接訪問真實對象,或者在遠程調用中需要使用代理類處理遠程方法調用的技術細節 (如 RMI),
也可能為了提升系統性能,對真實對象進行封裝,從而達到延遲加載的目的。
代理模式角色分為 4 種:
1.主題接口:定義代理類和真實主題的公共對外方法,也是代理類代理真實主題的方法;
2.真實主題:真正實現業務邏輯的類;
3.代理類:用來代理和封裝真實主題;
4.Main:客戶端,使用代理類和主題接口完成一些工作。
三、具體使用
1.靜態代理

![]()
/**
* Created by solverpeng on 2016/6/29.
*/
public interface Factory {
void say();
void produce();
}
Factory

![]()
/**
* NikeFatory
*
* @author solverpeng
* @create 2016-06-29-11:28
*/
public class NikeFactory implements Factory {
@Override
public void say() {
System.out.println("我要開始生產了!");
}
@Override
public void produce() {
System.out.println("正在生產Nike衣服!");
}
}
NikeFactory

![]()
/**
* NikeFactoryProxy
*
* @author solverpeng
* @create 2016-06-29-11:30
*/
public class NikeFactoryProxy implements Factory {
private NikeFactory nikeFactory;
public NikeFactoryProxy() {
this.nikeFactory = new NikeFactory();
}
@Override
public void say() {
before();
nikeFactory.say();
after();
}
@Override
public void produce() {
before();
nikeFactory.produce();
after();
}
private void after() {
System.out.println("大家做的不錯!");
}
private void before() {
System.out.println("在正式開始生產之前,我要說兩句!");
}
}
NikeFactoryProxy

![]()
@Test
public void testStaticProxy() {
NikeFactoryProxy nikeFactoryProxy = new NikeFactoryProxy();
nikeFactoryProxy.say();
nikeFactoryProxy.produce();
}
testStaticProxy
2.JDK動態代理

![]()
@Test
public void testJDKProxy() {
Factory proxyInstance = (Factory) Proxy.newProxyInstance(NikeFactory.class.getClassLoader(), NikeFactory.class.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(NikeFactory.class.newInstance(), args);
}
});
proxyInstance.say();
proxyInstance.produce();
}
testJDKProxy

![]()
/**
* 通用的代理生產工廠
*
* @author solverpeng
* @create 2016-06-29-11:45
*/
public class DynamicProxy implements InvocationHandler {
private Object target;
public DynamicProxy(Object target) {
this.target = target;
}
@SuppressWarnings("unchecked")
public <T> T getProxy() {
return (T)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(target, args);
}
}
DynamicProxy

![]()
@Test
public void testJDKProxy2() {
DynamicProxy dynamicProxy = new DynamicProxy(new NikeFactory());
Factory proxy = dynamicProxy.getProxy();
proxy.say();
proxy.produce();
}
testJDKProxy2
3.CGLIB動態代理(需要額外導入cglib包)

![]()
/**
* CglibProxy
*
* @author solverpeng
* @create 2016-06-29-14:40
*/
public class CglibProxy implements MethodInterceptor{
private static CglibProxy instance = new CglibProxy();
public CglibProxy() {
}
public static CglibProxy getInstance() {
return instance;
}
@SuppressWarnings("unchecked")
public <T> T getProxy(Class<T> cls) {
return (T)Enhancer.create(cls, this);
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
return methodProxy.invokeSuper(o, objects);
}
}
CglibProxy

![]()
@Test
public void testCglibProxy2() {
NikeFactory proxy = CglibProxy.getInstance().getProxy(NikeFactory.class);
proxy.say();
proxy.produce();
}
testCglibProxy2