首页 > 其他分享 >Spring IOC 和 AOP

Spring IOC 和 AOP

时间:2024-08-05 11:05:29浏览次数:7  
标签:Spring 代理 System AOP println IOC public out

Spring IOC 

  控制反转(IOC):Spring Bean对象统一创建交给IOC容器管理,来实现对象之间的解耦

  依赖注入(DI):构造器注入、setter方法注入、根据注解注入

Spring AOP

  AOP的实现关键在于代理模式,主要分为静态代理和动态代理
  静态代理的代表为AspectJ,动态代理以SpringAOP为例。

1)AspectJ是静态代理的增强,所谓静态代理,就是AOP框架会在编译阶段生成AOP代理类,因此也 称为编译时增强,他会在编译阶段将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的 AOP对象。

@Aspect 
@Component
public class MyAnnotionAop {
    // 定义切入点
    @Pointcut("execution(* com.test.AnnotionImpl.*.*(..))")
    public void point() {}
 
    // 前置通知
    @Before("point()")
    public void before() {
        System.out.println("前置");
    }
    // 后置通知 始终会执行
    @After("point()")
    public void after() {
        System.out.println("后置");
    }
    // 环绕通知
    @Around("point()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("环绕前");
        Object result = pjp.proceed();
        System.out.println("环绕后");
        return result;
    }
    // 后置 发生异常时不会执行
    @AfterReturning("point()")
    public void returning() {
        System.out.println("After returning 后置");
    }
    // 发生异常
    @AfterThrowing("point()")
    public void throwing() {
        System.out.println("发生异常了");
    }
}

 

2)Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行 时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理

JDK动态代理只提供接口的代理,不支持类的代理。核心InvocationHandler接口和Proxy类, InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一 起;接着,Proxy利用 InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的代理对 象。

public class JdkProxyDemo {

    interface Foo{
        void foo();
    }

    static class Target implements Foo{
        @Override
        public void foo() {
            System.out.println(" target foo");
        }
    }

    /**
     * jdk代理只能针对接口进行代理
     * 内部采用asm技术动态生成字节码()
     * @param args
     */
    public static void main(String[] args) {

        Target target = new Target();

        ClassLoader classLoader = JdkProxyDemo.class.getClassLoader();
        Foo proxy = (Foo)Proxy.newProxyInstance(classLoader, new Class[]{Foo.class}, new InvocationHandler() {
            //proxy 代理对象自身
            //method 正在执行的方法
            //方法参数
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("before");
                Object result = method.invoke(target, args);
                //代理类返回的是目标方法执行的结果
                System.out.println("after");
                return result;
            }
        });
        proxy.foo();
    }
}

 


②如果代理类没有实现 InvocationHandler 接口,那么Spring AOP会选择使用CGLIB来动态代理目 标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类 的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。CGLIB是通过继承的方式做的动态代 理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。
3)静态代理与动态代理区别在于生成AOP代理对象的时机不同,相对来说AspectJ的静态代理方式具 有更好的性能,但是AspectJ需要特定的编译器进行处理,而Spring AOP则无需特定的编译器处理。

标签:Spring,代理,System,AOP,println,IOC,public,out
From: https://www.cnblogs.com/darkb4dawn/p/18342800

相关文章