spring加载bean方式大全

1.配置文件

1
2
3
4
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("classpath:bean.xml");
applicationContext.refresh();
User user= applicationContext.getBean(User.class);

2.properties配置文件声明Bean的方式

properties:

1
2
user.(class) = com.sanyou.spring.bean.injection.User
user.username = sanyou
1
2
3
4
5
6
7
8
9
10
GenericApplicationContext applicationContext = new GenericApplicationContext();
//创建一个PropertiesBeanDefinitionReader,可以从properties读取Bean的信息,将读到的Bean信息放到applicationContext中
PropertiesBeanDefinitionReader propReader = new PropertiesBeanDefinitionReader(applicationContext);
//创建一个properties文件对应的Resource对象
Resource classPathResource = new ClassPathResource("PropertiesBeanInjectionDemo.properties");
//加载配置文件
propReader.loadBeanDefinitions(classPathResource);
applicationContext.refresh();
User user = applicationContext.getBean(User.class);
System.out.println(user);

3. @Import 方式

  • 导入普通bean,
  • 类实现了ImportSelector接口

  • 类实现了ImportBeanDefinitionRegistrar接口

使用场景配合 enableXXX注解使用

4. 注册BeanDefinition

以下两种都可以获取beanDefinitionRegister

  • ImportBeanDefinitionRegistrar
  • BeanDefinitionRegistryPostProcessor

5. 注册完整bean

拿到 SingletonBeanRegistry 直接注册,如实现 BeanFactoryPostProcessor

1
2
3
4
5
6
7
8
9
10
public class RegisterUserBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
User user = new User();
user.setUsername("用户名");
//将这个User对象注入到Spring容器中
beanFactory.registerSingleton("user", user);
}
}

6. 注入 beanFactory

7 其他扩展点

InstantiationAwareBeanPostProcessor

BeanPostProcess接口只在bean的初始化阶段进行扩展(注入spring上下文前后),而InstantiationAwareBeanPostProcessor接口在此基础上增加了3个方法,把可扩展的范围增加了实例化阶段和属性注入阶段。

该类主要的扩展点有以下5个方法,主要在bean生命周期的两大阶段:实例化阶段初始化阶段 ,下面一起进行说明,按调用顺序为:

  • postProcessBeforeInstantiation:实例化bean之前,相当于new这个bean之前
  • postProcessAfterInstantiation:实例化bean之后,相当于new这个bean之后
  • postProcessPropertyValues:bean已经实例化完成,在属性注入时阶段触发,@Autowired,@Resource等注解原理基于此方法实现
  • postProcessBeforeInitialization:初始化bean之前,相当于把bean注入spring上下文之前
  • postProcessAfterInitialization:初始化bean之后,相当于把bean注入spring上下文之后

ApplicationContextAwareProcessor

EnvironmentAware:用于获取EnviromentAware的一个扩展类,这个变量非常有用, 可以获得系统内的所有参数。当然个人认为这个Aware没必要去扩展,因为spring内部都可以通过注入的方式来直接获得。
EmbeddedValueResolverAware:用于获取StringValueResolver的一个扩展类, StringValueResolver用于获取基于String类型的properties的变量,一般我们都用@Value的方式去获取,如果实现了这个Aware接口,把StringValueResolver缓存起来,通过这个类去获取String类型的变量,效果是一样的。
ResourceLoaderAware:用于获取ResourceLoader的一个扩展类,ResourceLoader可以用于获取classpath内所有的资源对象,可以扩展此类来拿到ResourceLoader对象。
ApplicationEventPublisherAware:用于获取ApplicationEventPublisher的一个扩展类,ApplicationEventPublisher可以用来发布事件,结合ApplicationListener来共同使用,下文在介绍ApplicationListener时会详细提到。这个对象也可以通过spring注入的方式来获得。
MessageSourceAware:用于获取MessageSource的一个扩展类,MessageSource主要用来做国际化。
ApplicationContextAware:用来获取ApplicationContext的一个扩展类,ApplicationContext应该是很多人非常熟悉的一个类了,就是spring上下文管理器,可以手动的获取任何在spring上下文注册的bean,我们经常扩展这个接口来缓存spring上下文,包装成静态方法。同时ApplicationContext也实现了BeanFactoryMessageSourceApplicationEventPublisher等接口,也可以用来做相关接口的事情。

CommandLineRunner

触发时机为整个项目启动完毕后,自动执行