AOP概念
AOP采取横向抽取机制,取代了传统的纵向继承体系重复性代码(性能监视,缓存等等)
AOP底层的两种代理模式
- JDK动态代理
针对接口的业务类
public class MyJdkProxy implements InvocationHandler{
private UserDao userDao;
public MyJdkProxy(UserDao userDao){
this.userDao = userDao;
}
public Object createProxy(){
Object proxy = Proxy.newProxyInstance(userDao.getClass().getClassLoader(),userDao.getClass().getInterfaces(),this);
return proxy;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("save".equals(method.getName())){
System.out.println("权限验证。。。。。。。。。。。。。。。");
return method.invoke(userDao,args);
}
return method.invoke(userDao,args);
}
- CGLIB动态代理
当针对不使用接口的业务的时候,就无法使用JDK的动态代理。
CGLIB采用非常底层的字节码技术,可以为一个类创建子类,解决了无接口代理问题。
public class MyCglibProxy implements MethodInterceptor{
private ProductDao productDao;
public MyCglibProxy(ProductDao productDao){
this.productDao = productDao;
}
public Object createProxy(){
// 1.创建核心类
Enhancer enhancer = new Enhancer();
// 2.设置父类
enhancer.setSuperclass(productDao.getClass());
// 3.设置回调
enhancer.setCallback(this);
// 4.生成代理
Object proxy = enhancer.create();
return proxy;
}
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if("save".equals(method.getName())){
System.out.println("权限校验===================");
return methodProxy.invokeSuper(proxy,args);
}
return methodProxy.invokeSuper(proxy,args);
}
代理知识总结
-
Spring 在运行期,生成的动态代理对象,不需要特殊的编译器。
-
Spring AOP的底层就是通过JDK动态代理或者CGLIB动态代理技术为目标Bean执行横向织入。
1.若目标代理实现了若干接口,spring使用JDK的java.lang.refect.Proxy类代理。
2.若目标没有实现任何接口,spring使用CGLIB库生成目标对象的子类。 -
程序应该优先对接口创建代理,便于程序解耦维护。
-
标记final的方法,不能被代理,因为无法被重写。
-
Spring 只支持方法连接点,不提供属性连接。