首先要解释一下什么是代理模式:网上看了好多关于代理的解释我感觉都不是太令人满意,按照我个人的理解,代理模式的作用其实就是为一个对象提供一种代理以控制这个对象,然后把这个代理提供给别人来使用。代理模式会在那些情况下使用呢?在某些情况下,一个客户不想或者不能直接引用或者说在引用目标对象前后要进行一些额外的工作时候,代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式的角色有3种:
抽象角色:声明真实对象和代理对象的共同接口;
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作前后,附加其他的操作,相当于对真实对象进行封装一些额外的服务。
真实角色:代理角色所代表的真实对象,是代理最终要引用的对象。
静态代理:代理类中引用实在的被代理类;动态代理:代理类中不引用实在的被代理类,动态注入。
静态代理的实例:
抽象角色:UserDAO
publicinterface UserDAO {
publicvoid saveUser(User user);
}
真实角色:UserDAOImp
publicclass UserDAOImp implements UserDAO {
publicvoid saveUser(User user) {
}
}
代理角色:UserDAOProxy
publicclass UserDAOProxy implements UserDAO {
private UserDAO userDao;
UserDAOProxy(UserDAO userDao){
this.userDao = userDao;
}
publicvoid saveUser(User user) {
beforeSaveUser();
userDao.saveUser(user);
afterSaveUser();
}
privatevoid afterSaveUser() {
}
privatevoid beforeSaveUser() {
}
}
运行:
publicclass TestUserDAOProxy {
publicstaticvoid main(String[] args) {
UserDAO userDAO = new UserDAOImp();
UserDAO proxy = new UserDAOProxy(userDAO);
User user = new User();
proxy.saveUser(user);
}
}
动态代理的实例:
抽象角色:
publicinterface HelloWorld {
publicvoid sayHello();
}
真实角色:
publicclass HelloWorldImpl implements HelloWorld {
publicvoid sayHello() {
System.out.println("hello world");
}
}
Handler:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class HelloWorldHandler implements InvocationHandler {
Object obj;
HelloWorldHandler(Object obj) {
this.obj = obj;
}
public Object invoke(Object obj1, Method method, Object[] args)
throws Throwable {
this.doBefore();
Object o = method.invoke(obj, args);
this.doAfter();
return null;
}
public void doBefore() {
System.out.println("do this before");
}
public void doAfter() {
System.out.println("do this after");
}
}
具体调用:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
publicclass TestProxy {
publicstaticvoid main(String[] args) throws IllegalArgumentException,
InstantiationException, IllegalAccessException,
InvocationTargetException {
HelloWorld hw1 = new HelloWorldImpl();
HelloWorldHandler hh = new HelloWorldHandler(hw1);
HelloWorld proxy1 = (HelloWorld) Proxy.newProxyInstance(hw1.getClass()
.getClassLoader(), hw1.getClass().getInterfaces(), hh);
//proxy1就是动态代理,这样就减少了代理和添加业务方法的耦合,具体业务以及添加的业务在handler里面已经实现
proxy1.sayHello();
hw1.sayHello();
}
}
从此可以看出动态代理是基于interface 和classloader动态创建一个代理对象,如果你能理解这点就很容易理解spring 的aop
看下面一段代码,来源于spring in action:
<beans>
<bean id="quest"
class="com.springinaction.chapter01.knight.HolyGrailQuest" />
<bean id="knightTarget"
class="com.springinaction.chapter01.knight.KnightOfTheRoundTable">
<constructor-arg>
<value>Bedivere</value>
</constructor-arg>
<property name="quest">
<ref bean="quest" />
</property>
</bean>
<bean id="minstrel"
class="com.springinaction.chapter01.knight.MinstrelAdvice" />
<bean id="knight"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>
com.springinaction.chapter01.knight.Knight
</value>
<value>
com.springinaction.chapter01.knight.Knight2
</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>minstrel</value>
</list>
</property>
<property name="target">
<ref bean="knightTarget" />
</property>
</bean>
</beans>
BeanFactory factory = new XmlBeanFactory(new ClassPathResource(
"applicationContext.xml"));
Knight knight = (Knight) factory.getBean("knight");
//knight就是一个动态代理对象!
knight.embarkOnQuest();
看到上面的配置文件,然后再看一下动态代理,你会发现spring 的aop就是基于动态代理模式来实现的