Several common mode and differential Spring Bean registration and injected

Spring Registration Bean:

  1. Scan + component package label annotation (@ Controller, @ Service, @ Repository, @ Component), general project inside use.
  2. Use @Bean notes, when introduced into general use third-party components.
  3. @Import use annotations, generally used to quickly import a number of components.
  4. Use Interface + @Bean FactoryBean comment.

Scan + assembly denoted annotation packet (@ Controller, @ Service, @ Repository, @ Component)

We generally use are in project development in this way.

Use annotations @Bean

When the use of general import third-party components, such as a registration RedisTemplate:

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(redisConnectionFactory);

    FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);

    // 设置值(value)的序列化采用KryoRedisSerializer。
    redisTemplate.setValueSerializer(fastJsonRedisSerializer);
    redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
    // 设置键(key)的序列化采用StringRedisSerializer。
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setHashKeySerializer(new StringRedisSerializer());

    redisTemplate.afterPropertiesSet();
    return redisTemplate;
}

Use @Import comment

Generally used when rapid import a number of components, such as simultaneous registration of several animal:

@Configuration
@Import({DogTestBean.class, CatTestBean.class})
public class ImportConfig {

    @Bean
    public ImportTestBean importTestBean() {
        return new ImportTestBean();
    }
}

Container Bean:

打印 Spring 容器中的Bean  开始
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
importConfig
com.xiaolyuh.iimport.DogTestBean
com.xiaolyuh.iimport.CatTestBean
importTestBean
打印 Spring 容器中的Bean  结束

ImportSelector packet introduced

@Configuration
@Import({DogTestBean.class, CatTestBean.class, AnimalImportSelector.class})
public class ImportConfig {

    @Bean
    public ImportTestBean importTestBean() {
        return new ImportTestBean();
    }
}

public class AnimalImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        // 不能返回NULL,否则会报空指针异常,打断点可以看到源码
        return new String[]{"com.xiaolyuh.iimport.bean.FishTestBean",
                "com.xiaolyuh.iimport.bean.TigerTestBean" };
    }
}
打印 Spring 容器中的Bean  开始
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
importConfig
com.xiaolyuh.iimport.bean.DogTestBean
com.xiaolyuh.iimport.bean.CatTestBean
com.xiaolyuh.iimport.bean.FishTestBean
com.xiaolyuh.iimport.bean.TigerTestBean
importTestBean
打印 Spring 容器中的Bean  结束

selectImports()This method can not return NULL, otherwise null pointer exception will be reported, it is reported in a position out of the source code from the point of view:

	private Collection<SourceClass> asSourceClasses(String[] > classNames) throws IOException {
		List<SourceClass> annotatedClasses = new ArrayList<SourceClass>(classNames.length);
		for (String className : classNames) {
			annotatedClasses.add(asSourceClass(className));
		}
		return annotatedClasses;
	}

By ImportBeanDefinitionRegistrar custom registration

There are only zoo cats and dogs when I was a pig injected into it. ImportBeanDefinitionRegistrar registrar, in the process of registering the bean will perform in the final.

@Configuration
@Import({DogTestBean.class, CatTestBean.class, AnimalImportSelector.class, AnimalImportBeanDefinitionRegistrar.class})
public class ImportConfig {

    @Bean
    public ImportTestBean importTestBean() {
        return new ImportTestBean();
    }
}

public class AnimalImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     * @param importingClassMetadata 当前类的注解信息
     * @param registry               注册器,通过注册器将特定类注册到容器中
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 猫和狗的Bean我们可以声明一个注解,类似Spring Boot的条件注解
        boolean isContainsDog = registry.containsBeanDefinition(DogTestBean.class.getName());
        boolean isContainsCat = registry.containsBeanDefinition(CatTestBean.class.getName());

        if (isContainsDog && isContainsCat) {
            RootBeanDefinition beanDefinition = new RootBeanDefinition(PigTestBean.class);
            // 第一个参数是Bean id ,第二个是RootBeanDefinition
            registry.registerBeanDefinition("pigTestBean", beanDefinition);
        }
    }
}
打印 Spring 容器中的Bean  开始
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
importConfig
com.xiaolyuh.iimport.bean.DogTestBean
com.xiaolyuh.iimport.bean.CatTestBean
com.xiaolyuh.iimport.bean.FishTestBean
com.xiaolyuh.iimport.bean.TigerTestBean
importTestBean
pigTestBean
打印 Spring 容器中的Bean  结束
  1. Bean register this way, it must be packaged as Bean RootBeanDefinition.
  2. ImportBeanDefinitionRegistrar registrar, in the process of registering the bean will perform in the final.
  3. We can see the source code follow container is a Map,private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);

Use FactoryBean

@Configuration
@Import({DogTestBean.class, CatTestBean.class, AnimalImportSelector.class, AnimalImportBeanDefinitionRegistrar.class})
public class ImportConfig {

    @Bean
    public ImportTestBean importTestBean() {
        return new ImportTestBean();
    }

    // 最终注入的其实是 MonkeyTestBean 类
    @Bean
    public AnimalFactoryBean monkeyTestBean() {
        return new AnimalFactoryBean();
    }
}

public class AnimalFactoryBean implements FactoryBean {

    /**
     * 获取实例
     *
     * @return
     * @throws Exception
     */
    @Override
    public MonkeyTestBean getObject() throws Exception {

        return new MonkeyTestBean();
    }

    /**
     * 获取示例类型
     *
     * @return
     */
    @Override
    public Class<?> getObjectType() {
        return MonkeyTestBean.class;
    }

    /**
     * 是否单例
     *
     * @return
     */
    @Override
    public boolean isSingleton() {
        return true;
    }
}

Output:

打印 Spring 容器中的Bean  开始
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
importConfig
com.xiaolyuh.iimport.bean.DogTestBean
com.xiaolyuh.iimport.bean.CatTestBean
com.xiaolyuh.iimport.bean.FishTestBean
com.xiaolyuh.iimport.bean.TigerTestBean
importTestBean
monkeyTestBean
pigTestBean
打印 Spring 容器中的Bean  结束


开始获取容器中的Bean
14:07:12.533 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'monkeyTestBean'

MonkeyTestBean 初始化

14:07:12.534 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'monkeyTestBean'
true
我爱吃香蕉

Using this approach will register Bean to two containers, one is FactoryBean, one is true we need to register Bean, as in the demo MonkeyTestBean.
Using this way regardless of whether it is under the singleton instance of the real Bean Bean is the first acquisition of the time. That is after the container initialization is complete.
According to Bean's time to get the name, if added to a name in front of Bean &notation obtain factory Bean, Bean otherwise get our true registration.

Spring Bean injection of annotations:

  • @Autowired: annotation provided by Spring.
  • @inject: JSR-330 annotations provided.
  • @Resource: Notes JSP-250 provides.
  • '@Autowired' and '@Inject' they are by 'AutowiredAnnotationBeanPostProcessor' dependency injection class implementation, both interchangeability.
  • '@Resource' by 'CommonAnnotationBeanPostProcessor' class dependency injection, even so when they show dependency injection or very similar.

The following is a summary of their order of execution in implementing dependency injection:

@Autowired and @Inject

  1. Matches by Type
  2. Restricts by Qualifiers
  3. Matches by Name

@Resource

  1. Matches by Name
  2. Matches by Type
  3. Restricts by Qualifiers (ignored if match is found by name)

Source

https://github.com/wyh-spring-ecosystem-student/spring-boot-student/tree/releases

spring-boot-student-spring 工程

layering-cache

Born to monitor multi-level caching framework layering-cache This is my open source to achieve a multi-level caching framework, if interested can look at

发布了203 篇原创文章 · 获赞 145 · 访问量 85万+

Guess you like

Origin blog.csdn.net/xiaolyuh123/article/details/103289722