BeanDefinition表示Bean定义,有很多属性用来描述Bean的特点:
class,表示Bean类型
scope,表示Bean作用域,单例或原型等
lazyInit:表示Bean是否是懒加载
initMethodName:表示Bean初始化时要执行的方法
destroyMethodName:表示Bean销毁时要执行的方法
还有很多...
定义Bean的方式主要分为两种:
申明式定义
1、
2、@Bean
3、@Component(@Service,@Controller)
编程式定义
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
// 生成一个BeanDefinition对象,并设置beanClass为User.class,并注册到ApplicationContext中
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(User.class);
beanDefinition.setScope("prototype"); // 设置作用域
beanDefinition.setInitMethodName("init"); // 设置初始化方法
beanDefinition.setLazyInit(true); // 设置懒加载
context.registerBeanDefinition("user", beanDefinition);
System.out.println(context.getBean("user"));
BeanDefinition读取器,虽然开发中用的很少,但是源码中用得很多
把某个类转换为BeanDefinition,并且解析类上的注解
AnnotationConfigApplicationContext context = new
AnnotationConfigApplicationContext(AppConfig.class);
AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(context);
// 将User.class解析为BeanDefinition
annotatedBeanDefinitionReader.register(User.class);
System.out.println(context.getBean("user"));
可以解析的注解:@Conditional、@Scope、@Lazy、@Primary、@DependsOn、 @Role、@Description
解析
标签
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context);
int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");
System.out.println(context.getBean("user"));
扫描器,可以进行扫描,扫描某个包路径,对扫描到的类进行解析
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.refresh();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.scan("com.gax");
System.out.println(context.getBean("userService"));
Bean工厂,负责创建Bean,并且提供获取Bean的 API
ApplicationContext就是BeanFactory的一种
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory,
HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
...
}
HierarchicalBeanFactory: 支持父子Bean工厂,子Bean工厂获取不到时,可以到父Bean工厂去获取
ListableBeanFactory: 展示Bean的名字、展示Bean的数量、统计的信息、拿某一个类型的Bean,类似列表的功能
EnvironmentCapable: 获取环境变量的功能
ApplicationEventPublisher: 事件发布的功能
MessageSource: 国际化的功能
ResourcePatternResolver: 获取某些资源、解析某些资源的功能
Spring源码中,BeanFactory接口非常重要的实现类: DefaultListableBeanFactory
ApplicationContext.getBean() 调用的就是 DefaultListableBeanFactory 的getBean()方法
DefaultListableBeanFactory 可以单独使用:
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(User.class);
beanFactory.registerBeanDefinition("user", beanDefinition);
System.out.println(beanFactory.getBean("user"));
ApplicationContext是个接口,实际上也是一个BeanFactory,不过比BeanFactory 更加强大:
1、HierarchicalBeanFactory:拥有获取父BeanFactory的功能
2、ListableBeanFactory:拥有获取beanNames的功能
3、ResourcePatternResolver:资源加载器,可以一次性获取多个资源(文件资源等等)
4、EnvironmentCapable:可以获取运行时环境(没有设置运行时环境功能)
5、ApplicationEventPublisher:拥有广播事件的功能(没有添加事件监听器的功能)
6、MessageSource:拥有国际化功能
ApplicationContext两个重要的实现类:
1、AnnotationConfigApplicationContext
2、ClassPathXmlApplicationContext
定义一个MessageSource
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
ApplicationContext拥有国际化的功能,可以直接用
context.getMessage("test", null, new Locale("en_CN"))
可以利用ApplicationContext获取某个文件的内容
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Resource resource = context.getResource("file://D:\\UserService.java");
System.out.println(resource.contentLength());
System.out.println(resource.getFilename());
Resource resource1 = context.getResource("https://www.baidu.com");
System.out.println(resource1.contentLength());
System.out.println(resource1.getURL());
Resource resource2 = context.getResource("classpath:spring.xml");
System.out.println(resource2.contentLength());
System.out.println(resource2.getURL());
Resource[] resources = context.getResources("classpath:com/gax/*.class");
for (Resource resource : resources) {
System.out.println(resource.contentLength());
System.out.println(resource.getFilename());
}
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Map systemEnvironment = context.getEnvironment().getSystemEnvironment();
System.out.println(systemEnvironment); //操作系统层面的环境变量
Map systemProperties = context.getEnvironment().getSystemProperties();
System.out.println(systemProperties); //运行java通过-D指定的环境变量
MutablePropertySources propertySources = context.getEnvironment().getPropertySources();
System.out.println(propertySources); //最强大的,包含上面两种和PropertySources注解的变量
System.out.println(context.getEnvironment().getProperty("NO_PROXY")); //操作系统
System.out.println(context.getEnvironment().getProperty("sun.jnu.encoding")); //jvm -D指定
System.out.println(context.getEnvironment().getProperty("gax")); //property里面的
定义一个事件监听器
@Bean
public ApplicationListener applicationListener() {
return new ApplicationListener() {
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("接收到了一个事件");
}
};
}
发布一个事件
context.publishEvent("yeah");