Spring AOP原理以及基础

一、AOP是什么?

Aspect Oriented Programming(AOP) 面向切面编程。

名称 解释
静态代理 一个代理接口只能服务于一种类型的对象
动态代理 不必为特定对象与方法编写特定的代理对象,使用动态代理,可以使得一个处理者(Handler)服务于各个对象.

静态代理例子

//接口
public interface AInterface {
    void hi();
}
//实现
public class A implements AInterface {
    @Override
    public void hi() {
        System.out.println("hi");
    }
}
//代理类
public class AProxy implements AInterface {
    private AInterface a= new A();
    @Override
    public void hi() {
        System.out.println("Before invoke hi" );
        a.hi();
        System.out.println("After invoke hi");
    }
}
//代理调用
public static void main(String[] args) {
        AProxy aProxy = new AProxy();
        aProxy .hi();
}
输出:
Before invoke hi
hi
After invoke hi

动态代理例子

1 jdk proxy
  1. 定义一个InvocationHandler实例,它负责实现接口的方法调用;
  2. 通过Proxy.newProxyInstance()创建interface实例,它需要3个参数:
    1. 使用的ClassLoader,通常就是接口类的ClassLoader
    2. 需要实现的接口数组,至少需要传入一个接口进去;
    3. 用来处理接口方法调用的InvocationHandler实例。
  3. 将返回的Object强制转型为接口。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//接口
interface Hello {
    void morning(String name);
}
//调用
public class Main {

    public static void main(String[] args) {
    	//创建了一个Hello接口对象
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println(method);
                if (method.getName().equals("morning")) {
                    System.out.println("Good morning, " + args[0]);
                }
                return null;
            }
        };
        Hello hello = (Hello) Proxy.newProxyInstance(
            Hello.class.getClassLoader(), // 传入ClassLoader
            new Class[] { Hello.class }, // 传入要实现的接口
            handler); // 传入处理调用方法的InvocationHandler
        hello.morning("Bob");
    }
}
//动态代理实际上是JDK在运行期动态创建class字节码并加载的过程,它并没有什么黑魔法,把上面的动态代理改写为静态实现类大概长这样:

public class HelloDynamicProxy implements Hello {
    InvocationHandler handler;
    public HelloDynamicProxy(InvocationHandler handler) {
        this.handler = handler;
    }
    public void morning(String name) {
        handler.invoke(
           this,
           Hello.class.getMethod("morning"),
           new Object[] { name });
    }
}
2 cglib proxy

使用cglib实现动态代理,并不要求委托类必须实现接口,底层采用asm字节码生成框架生成代理类的字节码

package cglib;
//实现类
public class  Hello  {

    public void morning() {
        System.out.println("morning");
    }
}
//代理类
public class CglibTs implements MethodInterceptor{
 
	private Enhancer enhancer = new Enhancer();
	
	
    public Object getInstance(Object target) {
        this.target = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.target.getClass());
        // 设置回调方法
        enhancer.setCallback(this);
        // 创建代理对象
        return enhancer.create();
    }
    /**
     * 实现MethodInterceptor接口中重写的方法
     */
    @Override
    public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("事务开始。。。");
        Object result = proxy.invokeSuper(object, args);
        System.out.println("事务结束。。。");
        return result;
    }
	
}
//测试类
public class MainTest {
	public static void main(String[] args) {
		CglibTs ct = new CglibTs();
		Hello hello= (Hello) ct.getProxy(Hello.class);
		hello.morning()
	}
}
//结果
事务开始。。。
morning
事务结束。。



JDK动态代理只能对实现了接口的类生成代理,而不能针对类 。 CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 。 因为是继承,所以该类或方法最好不要声明成final ,final可以阻止继承和多态。

二、Spring AOP如何实现的?

Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。Spring创建代理的规则为:

1、默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了

2、当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可强制使用CGLIB

实现方式
  1. xml配置AOP

    spring-aop.xml 中,配置pointcut .编写实际的aspect 类 业务处理

  2. 注解配置AOP

    1 @Component 注解把AopConfig 加入到IOC容器中 ,2使用 @Aspect

三、使用场景

	日志记录,性能统计,安全控制,事务处理,异常处理

具体场景就是:将后台管理系统中的 操作日志写入到数据库记录,

  1. 自定义一个注解类
  2. 编写切面类 Pointcut到注解上 ,记录操作日志到数据库
  3. 将注解类配置到你要控制的方法

参考:
SpringAOP原理分析
Spring Boot实践——AOP实现
Spring Boot Aop
Spring AOP实现原理

发布了15 篇原创文章 · 获赞 0 · 访问量 403

猜你喜欢

转载自blog.csdn.net/u010020726/article/details/105000668
今日推荐