Spring FrameWork 概念
BeanDefinition
bean的定义,描述了很多bean的信息,
比如:
class:表示bean的类型
scope:表示bean的作用域
lazyInit:是否懒加载等
Bean定义:
- 声明式:
@Component(@Service,@Controller,@Repository)
@Bean - 编程式:
// Spring容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
// 生成一个BeanDefinition对象,让spring生成对应的bean
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
// 设置beanClass为A.class
beanDefinition.setBeanClass(A.class);
// 注册到ApplicationContext中
context.registerBeanDefinition("a", beanDefinition);
// 可从容器中取出刚刚设置生成的bean对象
System.out.println(context.getBean("a"));
BeanDefinitionReader 读取器
读取 解析生成:BeanDefinition,让spring生成对应的bean对象
xml式:XmlBeanDefinitionReader
注解式(类):AnnotatedBeanDefinitionReader
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
// 或得解析器
AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(context);
// 将A.class解析为BeanDefinition
BeanDefinition annotatedBeanDefinitionReader.register(A.class);
System.out.println(context.getBean("a"));
扫描式(包):ClassPathBeanDefinitionScanner
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.refresh();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
// 会扫描有@Component注解的类生产bean
scanner.scan("com.it");
System.out.println(context.getBean("aService"));
BeanFactory工厂
创建Bean,并提供Bean的工厂。
BeanFactory有个重要的实现:DefaultListableBeanFactory。
ApplicationContext
继承BeanFactory接口,同时ApplicationContext还继承了其它功能。如:
国际化:MessageSource
资源解析器:ResourcePatternResolver
广播事件发布:ApplicationEventPublisher
运行时环境变量获取:EnvironmentCapable
有两个比较重要的实现类
- AnnotationConfigApplicationContext
- ClassPathXmlApplicationContext
MessageSource 国际化
定义两个资源文件,可在代码中随意切换读取哪个配置文件
需要先定义一个MessageSource
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
资源文件:
使用:
context.getMessage("key", null, new Locale("en_CN"))
Resource 资源加载
可以直接通过Spring容器获取某个资源文件的内容:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
// file文件资源
Resource resource = context.getResource("file://D:\\project\\spring\\myspring\\src\\main\\java\\com\\it\\A.java");
System.out.println(resource.getFilename());
System.out.println(resource.contentLength());
// url资源
Resource resource1 = context.getResource("https://www.baidu.com");
System.out.println(resource1.contentLength());
System.out.println(resource1.getURL());
EnvironmentCapable 获取运行时环境
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
System.out.println(context.getEnvironment().getProperty("a")); System.out.println(context.getEnvironment().getProperty("a_b"));
可添加某个文件的参数到运行时环境中
@PropertySource("classpath:spring.properties")
ApplicationEventPublisher 广播事件发布
先定义一个事件监听器
@Bean
public ApplicationListener applicationListener() {
return new ApplicationListener() {
@Override public void onApplicationEvent(ApplicationEvent event) {
System.out.println("接收到事件");
} };
}
发布事件:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
context.publishEvent("aa");
ConversionService 类型转化
当要把string自动转换成A类型时:
@Component
public class aService {
@Value("nihao")
private A a;
public void test() {
System.out.println(a);
}
}
定义Spring转换器:
public class StringToAConverter implements ConditionalGenericConverter {
@Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return sourceType.getType().equals(String.class) && targetType.getType().equals(A.class);
}
@Override
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(String.class, A.class));
}
@Override
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
A a = new A();
a.setName((String)source);
return a;
}
}
向Spring中注册ConversionService:
@Bean
public ConversionServiceFactoryBean conversionService() {
ConversionServiceFactoryBean conversionServiceFactoryBean = new ConversionServiceFactoryBean();
conversionServiceFactoryBean.setConverters(Collections.singleton(new StringToAConverter()));
return conversionServiceFactoryBean;
}
当然,JDK也提供了转换器,只不过功能没Spring强大:PropertyEditor
Spring内部整合了JDK和Spring的转换器。即,两种都支持:TypeConverter
SimpleTypeConverter typeConverter = new SimpleTypeConverter();
typeConverter.setConversionService(conversionService);
A value = typeConverter.convertIfNecessary("1", A.class);
System.out.println(value);
OrderComparator 比较器
以用来根据实现Ordered接口或@Order注解(子类AnnotationAwareOrderComparator)来进行排序
如:
public class A implements Ordered {
@Override
public int getOrder() { return 3; }
}
BeanPostProcessor 后置处理器
每个Bean在创建时,都会执行初始化前,初始化后操作。
可以通过BeanPostProcessor来干涉Spring创建Bean的过程。
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("a".equals(beanName)) {
System.out.println("初始化前");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("a".equals(beanName)) {
System.out.println("初始化后");
}
return bean;
}
}
BeanFactoryPostProcessor Bean工厂的后置处理器
与BeanPostProcessor 类似
BeanPostProcessor是干涉Bean的创建过程,BeanFactoryPostProcessor是干涉BeanFactory的创 建过程。
@Component
public class MyFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("干涉beanFactory");
}
}
FactoryBean
通过FactoryBean,我们可以自己创建一个自定义的对象Bean。
(
对应了一个beanDefinition,两个bean对象,
一个beanName是&aaFactoryBean对应:AaFactoryBean(在singletonObjects单例池中(key也是aaFactoryBean));
一个beanName是aaFactoryBean对应:getObject()(factoryBeanObjectCache中)
bean初始化时只会把&aaFactoryBean,getBean(“aaFactoryBean”)时才会去调用getObject())
当然,需要注意的是:
通过这种方式创建的Bean。只会经过初始化后操作,其它Spring的声明周期不会经过。
@Component
public class AaFactoryBean implements FactoryBean {
@Override
public Object getObject() throws Exception {
AService aService = new AService();
return aService;
}
@Override
public Class<?> getObjectType() {
return AService.class;
}
}
与@Bean相比,@Bean是会经过完整的声明周期的。
ExcludeFilter和IncludeFilter
ExcludeFilter表示排除过滤器,IncludeFilter表示包 含过滤器。
@ComponentScan(
value = "com.it",
excludeFilters = {@ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
classes = AService.class)}.)
public class AppConfig {
// 排除了AService的扫描,即便AService上面有@Component注解
}
@ComponentScan(
value = "com.it",
includeFilters = {@ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
classes = AService.class)})
public class AppConfig {
// 扫描包下的AService,即便AService上面没有@Component注解,也会扫描生成Bean对象
}
FilterType分为:
- ANNOTATION:表示是否包含某个注解
- ASSIGNABLE_TYPE:表示是否是某个类
- ASPECTJ:表示否是符合某个Aspectj表达式
- REGEX:表示是否符合某个正则表达式
- CUSTOM:自定义
MetadataReader、ClassMetadata、 AnnotationMetadata 元数据读取器
Spring需要去解析类的信息时,比如类名、类中的方法、类上的注解时。
提供了MetadataReader元数据读取器。默认实现类:SimpleMetadataReader(ASM技术)
public static void main(String[] args) throws IOException {
SimpleMetadataReaderFactory simpleMetadataReaderFactory = new SimpleMetadataReaderFactory();
// 构造一个MetadataReader
MetadataReader metadataReader = simpleMetadataReaderFactory.getMetadataReader("com.it.service.AService");
// 得到一个ClassMetadata,并获取了类名
ClassMetadata classMetadata = metadataReader.getClassMetadata();
System.out.println(classMetadata.getClassName());
// 获取一个AnnotationMetadata,并获取类上的注解信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
for (String annotationType : annotationMetadata.getAnnotationTypes()) {
System.out.println(annotationType);
}
}
DefaultListableBeanFactory体系:
- AliasRegistry:支持别名功能,一个名字可以对应多个别名
- BeanDefinitionRegistry:可以注册、保存、移除、获取某个BeanDefinition
- BeanFactory:Bean工厂,可以根据某个bean的名字、或类型、或别名获取某个Bean对象
- SingletonBeanRegistry:可以直接注册、获取某个单例Bean
- SimpleAliasRegistry:它是一个类,实现了AliasRegistry接口中所定义的功能,支持别名功能
- ListableBeanFactory:在BeanFactory的基础上,增加了其他功能,可以获取所有
BeanDefinition的beanNames,可以根据某个类型获取对应的beanNames,可以根据某个类
型获取{类型:对应的Bean}的映射关系 - HierarchicalBeanFactory:在BeanFactory的基础上,添加了获取父BeanFactory的功能
- DefaultSingletonBeanRegistry:它是一个类,实现了SingletonBeanRegistry接口,拥有了直
接注册、获取某个单例Bean的功能 - ConfigurableBeanFactory:在HierarchicalBeanFactory和SingletonBeanRegistry的基础上,
添加了设置父BeanFactory、类加载器(表示可以指定某个类加载器进行类的加载)、设置
Spring EL表达式解析器(表示该BeanFactory可以解析EL表达式)、设置类型转化服务(表示
该BeanFactory可以进行类型转化)、可以添加BeanPostProcessor(表示该BeanFactory支持
Bean的后置处理器),可以合并BeanDefinition,可以销毁某个Bean等等功能 - FactoryBeanRegistrySupport:支持了FactoryBean的功能
- AutowireCapableBeanFactory:是直接继承了BeanFactory,在BeanFactory的基础上,支持
在创建Bean的过程中能对Bean进行自动装配 - AbstractBeanFactory:实现了ConfigurableBeanFactory接口,继承了
FactoryBeanRegistrySupport,这个BeanFactory的功能已经很全面了,但是不能自动装配和
获取beanNames - ConfigurableListableBeanFactory:继承了ListableBeanFactory、
AutowireCapableBeanFactory、ConfigurableBeanFactory - AbstractAutowireCapableBeanFactory:继承了AbstractBeanFactory,实现了
AutowireCapableBeanFactory,拥有了自动装配的功能 - DefaultListableBeanFactory:继承了AbstractAutowireCapableBeanFactory,实现了
ConfigurableListableBeanFactory接口和BeanDefinitionRegistry接口