Aop是将横向重复代码,纵向抽取出来,spring能够为容器中管理的对象生成动态代理对象。
例如在service层中实现事务管理,在servlet中解决乱码,在Action中用拦截器进行参数赋值。
AOP实现原理有动态代理和cglib代理。
动态代理对象必须实现接口,才能产生代理对象。
Cglib代理原理是对目标对象进行继承代理,如果目标对象呗final修饰,该类无法被cglib代理。
在使用时是有接口会优先使用动态代理。
实现aop的动态代理
先声明一个接口
public interface UserService {
void save();
}
实现类
public class UserServiceImpl implements UserService {
@Override
public void save() {
System.out.println("保存用户");
}
}
代理类
用到Proxy类和InvocationHandler接口
InvocationHandler接口只有invoke(Object proxy, Method method, Object[] args)
一个方法,proxy要代理的真实对象,method是要调用的真实对象的某个方法的Method对象,args是调用真实对象的某个方法时的参数。
Proxy类有重要的方法newProxyInstance(ClassLoader loader,
Class<?>[] interfaces, InvocationHandler h)
loader定义由哪个ClassLoader类加载器对象来对生成的代理对象进行加载,interfaces表示给代理对象提供的接口,代理对象表现为实现了该接口,则可以调用接口中的方法,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
public class UserServiceProxyFactory implements InvocationHandler {
private UserService us;
public UserServiceProxyFactory(UserService us) {
super();
this.us = us;
}
public UserService getUserServiceProxy() {
UserService usProxy = (UserService) Proxy.newProxyInstance(
UserServiceProxyFactory.class.getClassLoader(),
UserServiceImpl.class.getInterfaces(),
this);//当前代理类实现了InvocationHandler接口,所以这里直接使用当前类的对象this
return usProxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("打开");
Object invoke=method.invoke(us, args);
System.out.println("关闭");
return invoke;
}
}
测试方法
public static void main(String[] args) {
UserService us = new UserServiceImpl();
UserServiceProxyFactory factory = new UserServiceProxyFactory(us);
UserService usProxy = factory.getUserServiceProxy();
usProxy.save();
}
打开
保存用户
关闭