基于jdk的动态代理方式实现面向切面编程
相信大家在学习java编程的过程中对aop这个名字并不陌生也多少会对它有所了解,但是要说到他的底层原理的实现可能还是会一知半解。我在这里就把我所了解一些来给大家分享一下。
aop的大概原理就是向目标对象的方法中动态的追加一些代码逻辑,这样当通过代理类再次调用该方法时便是在调用已经改变了的原方法及aop代理的方法。
spring的aop底层主要是由以下两种代理方式所实现
- JDK动态代理.
- cglib动态代理
其中CGLIB的动态代理可以对没有实现接口的类生成代理.(采用的是比较底层的字节码技术,对类生成一个子类对象.)。
而我今天要在这里主要对JDK动态代理的实现aop来进行一个详细的说明,jdk动态代理与上述的CGLIB的动态代理所不同,它只能对实现了接口的类生成代理.,话不多说直接上代码。
//被代理类所实现接口
interface Human{
public void info();
public void fly();
}
//代理类
class SuperMan implements Human{
@Override
public void info() {
// TODO Auto-generated method stub
System.out.println("我是一个人");
}
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("我会飞");
}
}
接口的的定义可以为后面代理类与被代理类之间搭建桥梁
//将需要aop植入的代码逻辑封成类然后进行调用
class Heighten{
public void front() {
System.out.println("我是超人");
}
public void back() {
System.out.println("我很厉害");
}
}
//此类为目标方法与增添逻辑进行了整合,同时也实现了动态代理的功能
class MyInvocationHandler implements InvocationHandler{
Object obj;//被代理对象的声明
public void setObj(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
Heighten h=new Heighten();
h.front();
Object retrunVal=method.invoke(obj, args);
h.back();
return retrunVal;
}
}
MyInvocationHandler类实现动态代理的关键,它实现了InvocationHandler接口并重写了invoke方法在其中加入目标方法的需要增强的相关逻辑。
class MyProxy{
//动态创建代理类
public static Object getProxyInstance(Object obj){
MyInvocationHandler handler=new MyInvocationHandler();
handler.setObj(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), handler);
}
}
将对代理类的创建单独封装可以降低代码的复杂性,让整个调用流程更加清晰。
public class Aop{
@Test
public void test() {
SuperMan sm=new SuperMan();
Object obj=MyProxy.getProxyInstance(sm);
Human hu=(Human)obj;
hu.info();
hu.fly();
}
}
最后通过代理类调用方法,就会发现调用的是已经增强过的方法以此达到aop的横向切入效果而不必对原方法进行修改。
接下来运行结果:
我是超人
我是一个人
我很厉害
我是超人
我会飞
我很厉害