什么是代理模式:
代理模式的作用其实就是为一个对象提供一种代理以控制这个对象,然后把这个代理提供给别人来使用。
代理模式会在那些情况下使用呢 ?
在某些情况下,一个客户不想或者不能直接引用 或者说在引用目标对象前后要进行一些额外的工作 时候,代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式的角色有 3 种:
抽象角色 :声明真实对象和代理对象的共同接口;
代理角色 :代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口 以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作前后,附加其他的操作,相当于对真实对象进行封装 一些额外的服务。
真实角色 :代理角色所代表的真实对象,是代理最终要引用的对象。
===============================================================================
例子:
抽象角色:
package net.sx.staticProxy;
public interface SayHello {
public void say();
}
真实角色:
package net.sx.staticProxy;
public class SayHelloImpl implements SayHello{
public void say() {
System.err.println("hello!");;
}
}
===============================================================================
那么:
静态代理:
package net.sx.staticProxy;
public class SayHelloProxy implements SayHello{
SayHello s ;
public SayHelloProxy(SayHello s){
this.s=s;
}
public void say() {
System.err.println("before static");
s.say();
System.err.println("after static");
}
}
调用:
package net.sx.staticProxy;
public class Test {
public static void main(String[] args) {
SayHello a = new SayHelloImpl();
SayHello p = new SayHelloProxy(a);
p.say();
}
}
===============================================================================
动态代理:
package net.sx.dynamicProxy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyHandler implements InvocationHandler{
private Object proxyObj ;
public MyHandler(Object proxyObj){
this.proxyObj = proxyObj;
}
public Object invoke(Object proxy,Method method,Object[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException{
Object result = null;
System.err.println("before dynamic");
result = method.invoke(proxyObj, args);
System.err.println("after dynamic");
return result;
}
}
调用:
package net.sx.dynamicProxy;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
SayHello s = new SayHelloImpl();
SayHello p = (SayHello)Proxy.newProxyInstance(SayHello.class.getClassLoader(),
new Class[]{SayHello.class},
new MyHandler(s));
p.say();
}
}
===============================================================================
另用spring实现代理:
Advice:
package net.sx.springProxy;
import org.aopalliance.intercept.MethodInvocation;
import org.aopalliance.intercept.MethodInterceptor;
public class MyInterceptor implements MethodInterceptor{
public Object invoke(MethodInvocation invocation) throws Throwable{
Object result=null;
System.err.println("before spring");
result = invocation.proceed();
System.err.println("after spring");
return result;
}
}
xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="sayHelloImpl" class="net.sx.springProxy.SayHelloImpl" /> <bean id="myInterceptor" class="net.sx.springProxy.MyInterceptor" /> <bean id="sayHelloBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>net.sx.springProxy.SayHello</value> </property> <property name="interceptorNames"> <list> <value>myInterceptor</value> <value>sayHelloImpl</value> </list> </property> </bean> </beans>
调用:
package net.sx.springProxy;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new FileSystemXmlApplicationContext(
"/net/sx/springProxy/aop_bean.xml");
SayHello sayHelloBean = (SayHello)ctx.getBean("sayHelloBean");
sayHelloBean.say();
}
}