130.【Spring注解_AOP】(三)

简介: 130.【Spring注解_AOP】

(四)、扩展原理

1.BeanFactoryPostProcessor ->来定制和修改beanFactory的内容

在BeanFactory标准初始化之后调用,所有的bean定义已经保存加载到beanFactory,但是bean的实列还未创建

1.判断无参构造函数创建实列是否在BeanFactory之前还是之后?

1.BeanFactory的后置处理器MyBeanFactoryPostProcessor

package com.jsxs.etx;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
import java.util.Arrays;
/**
 * @Author Jsxs
 * @Date 2023/8/24 10:44
 * @PackageName:com.jsxs.etx
 * @ClassName: MyBeanFactoryPostProcessor
 * @Description: TODO
 * @Version 1.0
 */
@Component  ⭐注册组件
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { ⭐⭐ 继承接口
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("MyBeanFactoryPostProcessor->执行力postProcessBeanFactory方法");
        // 组件的数量
        int count = beanFactory.getBeanDefinitionCount();
        // 组件的名字
        String[] names = beanFactory.getBeanDefinitionNames();
        System.out.println("当前beanFactory中有"+count+"个Bean");
        System.out.println(Arrays.asList(names));
    }
}

2.实体类

package com.jsxs.bean;
/**
 * @Author Jsxs
 * @Date 2023/8/13 21:11
 * @PackageName:com.jsxs.bean
 * @ClassName: Yellow
 * @Description: TODO
 * @Version 1.0
 */
public class Yellow {
    public Yellow() {  // ⭐构造函数
        System.out.println("Yellow无参构造创建实列");
    }
}

3.配置类

package com.jsxs.etx;
import com.jsxs.bean.Yellow;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
 * @Author Jsxs
 * @Date 2023/8/24 10:38
 * @PackageName:com.jsxs.etx
 * @ClassName: EtxConfig
 * @Description: TODO   BeanFactoryPostProcessor : beanFactory的后置处理器 ⭐
 *                          在BeanFactory标准初始化之后调用,所有的bean定义已经保存加载到beanFactory,但是bean的实列还未创建
 *              在初始化创建其他组件前面执行
 * @Version 1.0
 */
@ComponentScan("com.jsxs.etx")  ⭐扫面组件
@Configuration
public class EtxConfig {
    @Bean  ⭐⭐ 将组件注册进来
    public Yellow yellow(){
        return new Yellow();
    }
}

4.测试

package com.jsxs.Test;
import com.jsxs.etx.EtxConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
 * @Author Jsxs
 * @Date 2023/8/24 10:48
 * @PackageName:com.jsxs.Test
 * @ClassName: IOC_ext
 * @Description: TODO
 * @Version 1.0
 */
public class IOC_ext {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(EtxConfig.class);
        applicationContext.close();
    }
}

所有的bean已经保存到beanFactory工厂中,但是实列依然还没有创建。在初始化创建其他组件前面执行

2.BeanDefinitionRegistryPostProcessor -> 额外添加组件

1.注册后置处理器

package com.jsxs.etx;
import com.jsxs.bean.Yellow;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;
/**
 * @Author Jsxs
 * @Date 2023/8/24 11:09
 * @PackageName:com.jsxs.etx
 * @ClassName: MyBeanDefinitionRegistryPostProcessor
 * @Description: TODO
 * @Version 1.0
 */
@Component  ⭐
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    // BeanDefinitionRegistry Bean定义信息的保存中心,以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实列 ⭐⭐
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("MyBeanDefinitionRegistryPostProcessor的数量是 "+registry.getBeanDefinitionCount()+"Registry ");
        // 创建一个组件 ⭐⭐⭐
        RootBeanDefinition beanDefinition = new RootBeanDefinition(Yellow.class);
        // 将刚才创建的组件注册进IOC中,且名字叫做hello ⭐⭐⭐⭐
        registry.registerBeanDefinition("hello",beanDefinition);
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("MyBeanDefinitionRegistryPostProcessor的数量是:"+beanFactory.getBeanDefinitionCount()+"   BeanFactory");
    }
}

2. 配置类 EtxConfig.java MyBeanFactoryPostProcessor.java Yellow.java IOC_ext.java 和上面的类是一样的

package com.jsxs.etx;
import com.jsxs.bean.Yellow;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
 * @Author Jsxs
 * @Date 2023/8/24 10:38
 * @PackageName:com.jsxs.etx
 * @ClassName: EtxConfig
 * @Description: TODO  1. BeanFactoryPostProcessor : beanFactory的后置处理器
 *                          在BeanFactory标准初始化之后调用,所有的bean定义已经保存加载到beanFactory,但是bean的实列还未创建
 *                          在初始化创建其他组件之前运行
 *                          (1).原理
 *                              (1.1).创建IOC容器
 *
 *                     2.BeanDefinitionRegistryPostProcessor
 *                          在所有的bean定义信息将要被加载,bean实列还未创建的时候执行。
 *                          优先于BeanFactoryPostProcessor执行,利用BeanDefinitionRegistryPostProcessor给容器中再额外的添加一些组件
 *                          (2).原理
 *                              (2.1).创建IOC容器
 *                              (2.2).refresh() 刷新容器 ->invokeBeanFactoryPostProcessors(beanFactory);.
 *                              
 *
 *
 * @Version 1.0
 */
@ComponentScan("com.jsxs.etx")
@Configuration
public class EtxConfig {
    @Bean
    public Yellow yellow(){
        return new Yellow();
    }
}

3.ApplicationListener -> 应用监听器

(1).ApplicationListener 的应用

1.事件-接口

package com.jsxs.etx;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
 * @Author Jsxs
 * @Date 2023/8/24 11:59
 * @PackageName:com.jsxs.etx
 * @ClassName: MyApplicationListener
 * @Description: TODO
 * @Version 1.0
 */
@Component  ⭐
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
    // 当容器中发布此事以后,方法触发  ⭐⭐
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        System.out.println("收到事件"+event);
    }
}

2.自定义事件

package com.jsxs.Test;
import com.jsxs.etx.EtxConfig;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
 * @Author Jsxs
 * @Date 2023/8/24 10:48
 * @PackageName:com.jsxs.Test
 * @ClassName: IOC_ext
 * @Description: TODO
 * @Version 1.0
 */
public class IOC_ext {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(EtxConfig.class);
        // 1.自定义发布一个事件 ⭐⭐⭐
        applicationContext.publishEvent(new ApplicationEvent(new String("我发布了一个事件")) {
        });
        applicationContext.close();
    }
}

3.配置类等其他的都没有变化

package com.jsxs.etx;
import com.jsxs.bean.Yellow;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
 * @Author Jsxs
 * @Date 2023/8/24 10:38
 * @PackageName:com.jsxs.etx
 * @ClassName: EtxConfig
 * @Description: TODO  1. BeanFactoryPostProcessor : beanFactory的后置处理器
 *                          在BeanFactory标准初始化之后调用,所有的bean定义已经保存加载到beanFactory,但是bean的实列还未创建
 *                          在初始化创建其他组件之前运行
 *                          (1).原理
 *                              (1.1).创建IOC容器
 *
 *                     2.BeanDefinitionRegistryPostProcessor
 *                          在所有的bean定义信息将要被加载,bean实列还未创建的时候执行。
 *                          优先于BeanFactoryPostProcessor执行,利用BeanDefinitionRegistryPostProcessor给容器中再额外的添加一些组件
 *                          (2).原理
 *                              (2.1).创建IOC容器
 *                              (2.2).refresh() 刷新容器 ->invokeBeanFactoryPostProcessors(beanFactory);.
 *                     3.ApplicationListener 监听容器中发布的事件。事件驱动模型开发
 *                          (1).监听ApplicationEvent及其下面的子事件
 *
 *                          步骤:
 *                              (1).写一个监听器来监听某个事件(ApplicationEvent及其子类)
 *                              (2).把监听器加入到容器中
 *                              (3).只要容器中有相关事件的发布,我们就能监听到这个事件
 *                                      ContextRefreshedEvent ->刷新事件 (所有的bean都已经创建)
 *                                      ContextClosedEvent -> 关闭事件
 *                              (4).自定义事件 ⭐⭐⭐⭐
 *                                  applicationContext.publishEvent(new ApplicationEvent(new String("我发布了一个事件")) {});
 *
 *
 *
 *
 * @Version 1.0
 */
@ComponentScan("com.jsxs.etx")
@Configuration
public class EtxConfig {
    @Bean
    public Yellow yellow(){
        return new Yellow();
    }
}

相关文章
|
9天前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
27 0
|
27天前
|
Java Spring
在使用Spring的`@Value`注解注入属性值时,有一些特殊字符需要注意
【10月更文挑战第9天】在使用Spring的`@Value`注解注入属性值时,需注意一些特殊字符的正确处理方法,包括空格、引号、反斜杠、新行、制表符、逗号、大括号、$、百分号及其他特殊字符。通过适当包裹或转义,确保这些字符能被正确解析和注入。
|
10天前
|
XML Java 数据安全/隐私保护
Spring Aop该如何使用
本文介绍了AOP(面向切面编程)的基本概念和术语,并通过具体业务场景演示了如何在Spring框架中使用Spring AOP。文章详细解释了切面、连接点、通知、切点等关键术语,并提供了完整的示例代码,帮助读者轻松理解和应用Spring AOP。
Spring Aop该如何使用
|
16天前
|
XML JSON Java
SpringBoot必须掌握的常用注解!
SpringBoot必须掌握的常用注解!
41 4
SpringBoot必须掌握的常用注解!
|
30天前
|
存储 缓存 Java
Spring高手之路23——AOP触发机制与代理逻辑的执行
本篇文章深入解析了Spring AOP代理的触发机制和执行流程,从源码角度详细讲解了Bean如何被AOP代理,包括代理对象的创建、配置与执行逻辑,帮助读者全面掌握Spring AOP的核心技术。
37 3
Spring高手之路23——AOP触发机制与代理逻辑的执行
|
1月前
|
XML Java 数据格式
使用完全注解的方式进行AOP功能实现(@Aspect+@Configuration+@EnableAspectJAutoProxy+@ComponentScan)
本文介绍了如何使用Spring框架的注解方式实现AOP(面向切面编程)。当目标对象没有实现接口时,Spring会自动采用CGLIB库进行动态代理。文中详细解释了常用的AOP注解,如`@Aspect`、`@Pointcut`、`@Before`等,并提供了完整的示例代码,包括业务逻辑类`User`、配置类`SpringConfiguration`、切面类`LoggingAspect`以及测试类`TestAnnotationConfig`。通过这些示例,展示了如何在方法执行前后添加日志记录等切面逻辑。
92 2
使用完全注解的方式进行AOP功能实现(@Aspect+@Configuration+@EnableAspectJAutoProxy+@ComponentScan)
|
15天前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
27 1
|
17天前
|
存储 缓存 Java
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
58 2
|
17天前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
33 1
|
11天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
24 0