讲一下spring aop

面试官:讲一下spring aop

回答:AOP是指的spring中的面向切面编程,就是把一些系统的业务比如日志管理,事务管理等变成横向切面,将其跟核心业务逻辑代码分开,使代码比较简洁。等到要用到这个切面的时候,就把它织入到目标对象中成代理对象,实际上操作的是代理对象,

 

假如没有aop,在做日志处理的时候,我们会在每个方法中添加日志处理,比如

但大多数的日子处理代码是相同的,为了实现代码复用,我们可能把日志处理抽离成一个新的方法。但是这样我们仍然必须手动插入这些方法。
但这样两个方法就是强耦合的,假如此时我们不需要这个功能了,或者想换成其他功能,那么就必须一个个修改。

通过动态代理,可以在指定位置执行对应流程。这样就可以将一些横向的功能抽离出来形成一个独立的模块,然后在指定位置插入这些功能。这样的思想,被称为面向切面编程,亦即AOP。
       切面编程,就是在你项目原有的功能基础上,通过AOP去添加新的功能,这些功能是建立在原有功能的基础上的,而且原有的功能并不知道你已经添加了新的功能。

AOP的底层实现是动态代理,它涉及到的动态代理是由两种,

代理机制:

  ●  Spring 的 AOP 的底层用到两种代理机制:

  ●  JDK 的动态代理 :针对实现了接口的类产生代理.

  ●  Cglib 的动态代理:针对没有实现接口的类产生代理. 应用的是底层的字节码增强的技术 生成当前类的子类对象.

JDK动态代理的例子:

 JDK动态代理的一般步骤如下:

       创建被代理的接口和类;

       实现InvocationHandler接口,对目标接口中声明的所有方法进行统一处理;

      调用Proxy的静态方法,创建代理类并生成相应的代理对象;

       使用代理。

1.创建被代理的接口和类。

// 抽象主题角色
public interface HelloService {

    String hello(String name);

    String hi(String msg);
}

// 具体(真实)主题角色
public class HelloServiceImpl implements HelloService{
    @Override
    public String hello(String name) {
        return "Hello " + name;
    }

    @Override
    public String hi(String msg) {
        return "Hi, " + msg;
    }
}

2.  实现InvocationHandler接口,对目标接口中声明的所有方法进行统一处理;

        这里是真正对目标类进行增强的地方

  是通过实现InvocationHandler的invoke方法中实现功能上的增强的。

public class MyInvocationHandler implements InvocationHandler{

    // 真实业务对象
    private Object target;

    public MyInvocationHandler(Object target){
        this.target = target;
    }

     @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 增强逻辑
        System.out.println("PROXY : " + proxy.getClass().getName());

        // 反射调用,目标方法
        Object result = method.invoke(target, args);

        // 增强逻辑
        System.out.println(method.getName() + " : " + result);

        return result;
    }
}

3.创建代理类并生成相应的代理对象

public class test{
  HelloService proxy = (HelloService)Proxy.newProxyInstance(HelloService.class.getClassLoader(),
helloService.getClass().getInterfaces(), new MyInvocationHandler(helloService));

  proxy.hello("rico");
  proxy.hi("panda");



}

猜你喜欢

转载自blog.csdn.net/hezuo1181/article/details/82830854