This is the 21st day of my participation in the August More Text Challenge

Aware of interface

  1. Aware means Aware, and by implementing the Aware interface and rewriting its methods, you can get the current operating environment from the context

  2. Common Aware interfaces

    • BeanNameAware
    • BeanFactoryAware
    • BeanClassLoaderAware
    • ApplicationContextAware
  3. use

    @Component
    @ToString
    public class TestService  implements BeanNameAware.BeanClassLoaderAware {
        private String beanName;
        private ClassLoader classLoader;
    
        @Override
        public void setBeanClassLoader(ClassLoader classLoader) {
            this.classLoader = classLoader;
        }
    
        @Override
        public void setBeanName(String name) {
            this.beanName= name; }}Copy the code

InitializingBean

  1. The InitializingBean interface is used to perform custom operations at the Bean initialization stage, and also to type DisposableBean

  2. use

    @Component
    public class TestBean implements InitializingBean.DisposableBean {
    
        // called after the bean has set its properties
        @Override
        public void afterPropertiesSet(a) throws Exception {
            // Initialize the operation
            System.out.println("TestBean init");
        }
    
        // called after destruction
        @Override
        public void destroy(a) throws Exception {
            // Release resources
            System.out.println("TestBean destroy"); }}Copy the code

BeanPostProcessor

  1. BeanPostProcessor, the Bean’s post-processor, is effective for all beans, unlike InitializingBeans

  2. use

    @Component
    public class TestPostProcessor implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("Before Bean initialization");
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("After Bean initialization");
            returnbean; }}Copy the code
  3. BeanPostProcessor can be used in a variety of scenarios. It can get the Bean object that is being initialized and then perform some customized operations based on the Bean object, such as determining whether the Bean is a specific object and obtaining the Bean’s annotation metadata

  4. Spring has a lot of BeanPostProcessor built in to improve its functionality

BeanFactoryPostProcessor

  1. The BeanFactoryPostProcessor is a post-processor in the Bean factory that is typically used to modify the BeanDefinition in context

  2. use

    @Component
    public class TestFactoryPostProcessor implements BeanFactoryPostProcessor {
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            System.out.println("All BeanDefinitions have been loaded, but the Bean has not yet been instantiated.");
            
            // Dynamically add BeanDefinition
            / / into subclasses DefaultListableBeanFactory
            DefaultListableBeanFactory defaultBeanFactory = 
                (DefaultListableBeanFactory) beanFactory;
            // New a beanDefinition object
            GenericBeanDefinition b = new GenericBeanDefinition();
            b.setBeanClass(Testbean.class);
            // Add a beanDefinition object
            defaultBeanFactory.registerBeanDefinition("testBean", b);
            
            // Get BeanDefinition dynamically
    		Object o = defaultBeanFactory.getBean("testBean")}}Copy the code
  3. BeanDefinition contains the information Spring needs to instantiate a Bean

ImportSelector

  1. ImportSelector can dynamically return classes that need to be container-managed, usually to return external configuration classes

    public class TestImportSelector implements ImportSelector {
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            
            // AnnotationMetadata stores AnnotationMetadata information
            // Can dynamically return the class name that needs to be managed by the container
            if (importingClassMetadata.hasAnnotation("")) {
                // Determine whether an annotation is included
            }
            
            // Add the TestBean to the Spring container
            return new String[]{"com.example.pojo.TestBean"}; }}Copy the code
  2. In a class annotated with @Configuration, Import ImportSelector via @import to make it work

    @Configuration
    @Import(TestImportSelector.class)
    public class TestConfig {}Copy the code

ImportBeanDefinitionRegistrar

  1. ImportBeanDefinitionRegistrar is also used with @ Import, can be directly will Bean registered into the container

  2. use

    public class TestRegistrar implements ImportBeanDefinitionRegistrar {
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            GenericBeanDefinition b = new GenericBeanDefinition();
            b.setBeanClass(NotScanBean.class);
            b.setLazyInit(true);
            // Register to the containerregistry.registerBeanDefinition(NotScanBean.class.getName(), b); }}Copy the code

FactoryBean

  1. Factorybeans provide a more flexible way to create beans and are often used to create a class of beans

  2. When a Bean implements a FactoryBean, the Bean object obtained by getBean(String BeanName) is not the implementation-class object of the FactoryBean, but the object returned by the implementation-class getObject() method. BeanName is preceded by an & to get the implementation object of a FactoryBean

  3. use

    @Component
    public class TestFactoryBean implements FactoryBean<TestBean> {
        @Override
        public TestBean getObject(a) throws Exception {
    
            // Configure the Bean
            // Proxy, modifier, etc
    
            return new TestBean();
        }
    
        @Override
        publicClass<? > getObjectType() {return null; }}Copy the code

ApplicationListener

  1. ApplicationListener is the core interface that Spring implements the event mechanism and is part of the observer design pattern

  2. ApplicationContext can publish ApplicationEvent events, after which all ApplicationListeners are called back

  3. Custom ApplicationEvent

    public class TestApplicationEvent extends ApplicationEvent {
    
        public TestApplicationEvent(Object source) {
            super(source);
        }
    
        public void hello(a){
            System.out.println("Hello Word!"); }}Copy the code
  4. Custom ApplicationListener

    @Component
    public class TestApplicationListener implements ApplicationListener {
    
        @Override
        public void onApplicationEvent(ApplicationEvent event) {
            if (event instanceofTestApplicationEvent) { TestApplicationEvent testApplicationEvent = (TestApplicationEvent) event; testApplicationEvent.hello(); }}}Copy the code
  5. Obtain the ApplicationContext object and publish applicationEvents by injecting ApplicationContext or implementing the ApplicationContextAware interface

    @SpringBootTest
    class DemoApplicationTests {
    
        @Autowired
        ApplicationContext applicationContext;
    
        @Test
        public void test(a) {
            applicationContext.publishEvent(new TestApplicationEvent(newDemoApplication())); }}// Hello Word!
    Copy the code

ApplicationRunner

  1. The SpringBoot application launches successfully with the callRunners method, and all ApplicationRunner implementation classes are called back

  2. Implement AppilcationRunner, and the ApplicationArguments type is used to receive startup arguments

    @Component
    public class MyApplicationRunner implements ApplicationRunner {
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            System.out.println("Original parameter:" + Arrays.asList(args.getSourceArgs()));
            Set<String> keys = args.getOptionNames();
            for (String key : keys) {
                System.out.println("Parse key: [" + key + "] value: " + args.getOptionValues(key));
            }
            System.out.println("No OptionName argument:"+ args.getNonOptionArgs()); }}// Example: a=1 --b -- c
    / / print = >
    // Original parameter: [--a=1, --b, c]
    [a] value: [1]
    Key: [b] value: []
    // No OptionName parameter: [c]
    Copy the code
  3. CommandLineRunner is similar to ApplicationRunner, but only retrieves raw parameters that have not been parsed