AOP (Aspect Oriented Programming),面向切面编程,是JAVA面向对象特性的重要补充,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。使用AOP最大的功能是安全控制、事务控制、日志记录等。
动态代理,针对于预编译的代理设计模式(静态)而言,在程序运行过程中通过反射机制创建而成。
动态代理是面向接口的,也就是说只有一个类实现了某一个接口,这个接口中的方法才能够被代理使用,从而在方法执行之前或者之后执行某些代码。
下面对接口UserService的add方法增加执行前和执行后的执行代码,Spring AOP使用动态代理的方式原理可见一斑:
/**
* 动态代理接口
* 使用动态代理,必须使用接口方式,否则代理类没有接口中的目标方法
*/
public interface UserService {
/**
* 代理的目标方法
*/
public void add();
}
接口实现类
/**
* @author Administrator
* 动态代理接口
* 使用动态代理,必须使用接口方式,否则代理类没有接口中的目标方法
*/
public interface UserService {
/**
* 代理的目标方法
*/
public void add();
}
InvocationHandler及测试方法
public class ZoneInvocationHandler implements InvocationHandler {
//目标对象
private Object target;
ZoneInvocationHandler(Object tar){
super();
this.target = tar;
}
private Object before(){
System.out.println("------------------before------------------");
return null;
}
private Object after(){
System.out.println("------------------after------------------");
return null;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 在目标对象的方法执行之前简单的打印一下
before();
// 执行目标对象的方法
Object result = method.invoke(target, args);
// 在目标对象的方法执行之后简单的打印一下
after();
return result;
}
/**
* 获取目标对象的代理对象
* @return 代理对象
*/
public Object getProxy() {
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
target.getClass().getInterfaces(), this);
}
public static void main(String[] args) {
// 实例化目标对象
UserService userService = new UserServiceImpl();
// 实例化InvocationHandler
ZoneInvocationHandler invocationHandler = new ZoneInvocationHandler(userService);
// 根据目标对象生成代理对象
UserService proxy = (UserService) invocationHandler.getProxy();
// 调用代理对象的方法
proxy.add();
//可将代理类写入硬盘
ProxyGeneratorUtils.writeProxyClassToHardDisk("F:/$Proxy11.class");
}
}
使用jd-gui工具打开$Proxy11.class可以看到代理类
$Proxy11继承于Proxy,并实现了接口UserInterface,并在add方法中,执行了关联的ZoneInvocationHandler对象的invoke方法,这个方法在add方法前后执行了before和after代码。