Spring
2023-03-30 08:56:21
本文总阅读量
  • BeanFactory是最顶级的接口,是核心容器,定义了getBean()

  • ApplicationContext接口间接继承了BeanFactory,同时还继承了其他的接口,扩展了功能(例如:国际化、通配符方式获取一组Resource资源、整合Environment环境、事件发布与监听)

    • ApplicationContext的实现类组合了BeanFactory。例如:SpringApplication.run()返回的context是ConfigurableApplicationContext继承于ApplicationContext,实现类是AnnotationConfigServletWebServerApplicationContext,组合的BeanFactory的实现类是DefaultListableBeanFactory,这里面就有SingletonObjects
  • 有很多容器的实现类比如:最重要的DefaultListableBeanFactory,还有基于xml的,基于注解的,xxxxApplicationContext这种容器的实现类是组合了DefaultListableBeanFactory。需要通过向这些容器注册BeanDefinition对象,使他们为我们创建Bean。

    • 创建Bean的过程
  • 注册了某一个Class的Definition之后,并不会将@Configuration里面的@Bean注册进去,这就需要一些操作来完成这些工作,有很多的后置处理器,这里也用到了模板设计模式。

    • 后置处理器:
      • BeanFactory的后置处理器,可以解析@Configuration里面的@Bean
      • Bean的后置处理器,可以解析@Autowired,@Resource
    • 模板方法模式
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      public class TemplateMethodPattern {

      interface Processor {
      void method();
      }

      public static class Student {
      private final List<Processor> list = new ArrayList<>();
      private final String name = "Tom";

      public void stuMethod() {
      System.out.println("name: " + name + "do something...");
      for (Processor processor : list) {
      processor.method();
      }
      }

      public void addProcessor(Processor processor) {
      list.add(processor);
      }
      }

      public static void main(String[] args) {
      Student student = new Student();
      student.addProcessor(() -> System.out.println("扩展1"));
      student.addProcessor(() -> System.out.println("扩展2"));
      student.stuMethod();
      }
      }
  • Bean的生命周期

    1. 创建(构造器or工厂方法)。前后可增强
    2. 依赖注入(@Autowired@Resource@Value)。前可增强
    3. 初始化(@PostConstruct)。前后可增强
    4. 销毁(@PreDestroy)。前可增强
  • 向容器中注册Bean的后置处理器,用于解析@Autowired、@Value@Resource@PostConstruct@PreDestroy等等,让他们起作用

  • 向容器中注册BeanFactory的后置处理器,用于解析@ComponentScan、@Bean@Import@ImportResource@MapperScanner等等

  • Aware接口及InitializingBean接口

  • 初始化与销毁、Scope

  • AOP的实现方式

    1. 代理
      • JDK
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        public class JdkProxy {
        interface Foo {
        void foo();
        }

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

        // jdk 只能针对接口代理
        public static void main(String[] param) throws IOException {
        // 目标对象
        Target target = new Target();
        // 为什么需要类加载?正常流程:代码 -> 编译成字节码 -> 类加载
        // 代理类是没有代码的
        ClassLoader loader = JdkProxy.class.getClassLoader(); // 用来加载在运行期间动态生成的字节码
        Foo proxy = (Foo) Proxy.newProxyInstance(loader, new Class[]{Foo.class}, new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before...");
        // 目标.方法(参数)
        // 方法.invoke(目标, 参数);
        Object result = method.invoke(target, args);
        System.out.println("after....");
        return result; // 让代理也返回目标方法执行的结果
        }
        });

        System.out.println(proxy.getClass());

        proxy.foo();
        // 代理和target是兄弟关系
        }
        }
      • cglib
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        public class CglibProxy {

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

        // 目标类不能是final的,因为不能继承,方法不能是final的,因为不能重写
        // 代理是子类型, 目标是父类型
        public static void main(String[] param) {
        Target proxy = (Target) Enhancer.create(Target.class, new MethodInterceptor() {
        @Override
        public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("before...");
        // Object result = method.invoke(target, args); // 用方法反射调用目标
        // methodProxy 它可以避免反射调用
        // Object result = methodProxy.invoke(target, args); // 内部没有用反射, 需要目标 (spring)
        Object result = methodProxy.invokeSuper(o, args); // 内部没有用反射, 需要代理
        System.out.println("after...");
        return result;
        }
        });

        proxy.foo();

        }
        }
    2. AspectJ
      • ajc编译器编译时修改字节码
      • 类加载时修改字节码
上一页
2023-03-30 08:56:21
下一页