什么是AOP
AOP即面向切面编程,能够让我们在不影响原来功能的基础上,对程序进行横向的扩展。
我的理解是:如果某个类的某个方法是封装好的,我们在对这个方法进行调用的时候想加一些属于自己的东西,对这个方法的执行进行一定的干预,当然前提是不能改变破坏原来的类。这个时候就需要AOP思想,把这个方法,即切点拓展成一个切面进行操作。即生成该类的代理,对代理进行操作。
例如:给这个方法加日志,对这个方法的执行进行拦截,事务处理,生成缓存等操作。
实现代理的方法
动态代理。动态代理也是重要的设计模式之一。
实现AOP的动态代理有两种,JDK动态代理和CGLIB动态代理。
1.JDK动态代理
利用java.lang.reflect.Proxy类,也就是java的反射机制接收类,但局限于需要被代理的对象必须实现一个接口,如果被代理的对象没有实现任何的接口,或者被代理的方法没有相应的接口,就无法得到代理对象。这时候就需要使用CGLIB进行代理。
2.CGLIB动态代理
原理实际上是生成被代理类的子类字节码,即通过继承的方法,重写父类的方法对父类的特定方法进行增强。由于其字节码都是按照jvm编译后的class文件的规范编写的,因而其可以被jvm正常加载并运行,当然也有局限,如果被代理类的方法被声明final类型,那么Cglib代理是无法正常工作的,因为final类型方法不能被重写。
动态代理区别于“多态”,多态就是同一个接口,使用不同的实例而执行不同操作。多态的存在要有3个必要条件:继承,方法重写,父类引用指向子类对象。而动态代理是一种java的设计模式,也并非要继承和重新父类的所有方法。
下面先给出实现代理的两种方法的代码
private <T> T cglibProxy(Class<?> klass, Object object) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(klass);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
return doInvoker(object, method, args);
}
});
return (T) enhancer.create();
}
private <T> T jdkProxy(Class<?> klass, Object object) {
ClassLoader classLoader = klass.getClassLoader();
Class<?>[] interfaces = klass.getInterfaces();
return (T) Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return doInvoker(object, method, args);
}
});
}
以上就是实现代理的两种方式,这里有个doInvoker方法,即根据反射机制实现对原方法的调用!这里指的一提的就是:当我们使用代理对象执行方法的时候,其内部调用方法的对象其实还是原对象,并不是代理对象执行该方法!
手写实现一个AOP的思路