03Spring底层架构核心概念解析
为了感谢罕哥对我工作的帮助,特此记录下学习过程,期待成为和罕哥一样优秀的人
时间:2024.7.13
内容:spring源码课程3学习记录
一、BeanDefinition
BeanDefinition表示Bean的定义,BeanDefinition中存在很多属性用来描述一个Bean的特点
class:表示Bean类型
scope:表示Bean的作用域(单例/原型)
lazyInit:表示Bean是否是懒加载
initMethodName:表示Bean初始化时要执行的方法
destroyMethodName:表示Bean销毁时要执行的方法
........
二、在Spring中,定义Bean的方式
声明式定义:
1、<bean/>
2、@Bean
3、@Component(@Service,@Controller)
编程式定义:
直接通过BeanDefinition,此处就是Spring源码定义一个Bean的实现过程
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(UserService.class);
beanDefinition.setScope("prototype");
//把beanDefinition注册到容器中
context.registerBeanDefinition("userService",beanDefinition);
UserService userService = (UserService)context.getBean("userService");
userService.test();
三、Spring内部的组件
下面的组件在Spring中使用的很少,但是在源码中使用的很多,学习有利于理解源码
1、AnnotatedBeanDefinitionReader
可以直接把某个类转换为BeanDefinition,并读取解析类的注解。就是BeanDefiniton读取器。把读到的BeanDefinition存到容器中
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(context);
//将UserService.class解析为BeanDefinition
annotatedBeanDefinitionReader.register(UserService.class);
System.out.println(context.getBean("userService"));
2、XmlBeanDefinitionReader
可以解析<bean/>标签
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context);
xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");
3、ClassPathBeanDefinitionScanner
扫描器,和BeanDefinitionReader类似,对某个包路径就行扫描,对扫描的类进行解析,如果存在@Component注解,就会把这个类解析为一个BeanDefinition
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.refresh();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
int i = scanner.scan("org.com.zhuyn");
System.out.println(context.getBean("userService"));
四、ApplicationContext与BeanFactory
ApplicationContext继承了BeanFactory,除此之外还继承了别的
ApplicationEnventPublisher:事件发布器
EnvironmentCapable:获取环境变量的功能
MessageSource:进行国际化的功能
ResourcepatternResolver:解析某些资源的功能
因此,当我们使用applicationContext.getBean("xxx")的时候,本质上是使用的DefaultListableBeanFactory来获取的。
1、ResourcepatternResolver
(1)拿文件资源
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Resource resource = context.getResource("file://C:\\Usersxxxxxxxxx"");
System.out.println(resource.contentLength());
(2)拿url
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Resource resource = context.getResource("https://www.baidu.com");
System.out.println(resource.contentLength());
System.out.println(resource.getURL());
这里的Resource可以拿很多种资源。
2、ApplicationEnventPublisher
在工作当中可以直接定义一个事件发布器、
@Component
public class UserService {
private ApplicationEventPublisher applicationEventPublisher;
}
也可以使用applicationContext自带的事件发布器
@Component
public class UserService {
@Autowired
private ApplicationContext context;
public void test(){
context.publishEvent("hello");
System.out.println("test");
}
}
事件监听器
@ComponentScan("org.com.zhuyn")
public class AppConfig {
@Bean
public ApplicationListener applicationListener(){
return new ApplicationListener() {
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
System.out.println("发布了一个事件"+applicationEvent);
}
};
}
}
五、类型转化
1、PropertyEditor
把字符串转换成user对象。
类型转换器
public class StringToUserPropertyEditor extends PropertyEditorSupport implements PropertyEditor {
@Override
public void setAsText(String text) throws IllegalArgumentException {
User user = new User();
user.setName(text);
this.setValue(user);
}
}
类型转换器的使用
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
StringToUserPropertyEditor propertyEditor = new StringToUserPropertyEditor();
propertyEditor.setAsText("xiaoming");
User user = (User) propertyEditor.getValue();
System.out.println(user.getName());
在spring内部也使用到了类型转换,例如当我们使用这个
UserService userservice = context.getBean("userService",UserService.class)
我们传一个string类型,得到一个UserService类型的对象。
2、ConversionService
3、TypeConverter
六、比较器
可以根据@Order注解或实现Ordered接口来执行值进行比较,从而可以进行排序。
Ordered接口实现方法:
1、在类上实现Ordered接口
2、使用OrderComparator构建比较器
类A
public class A implements Ordered {
@Override
public int getOrder() {
return 1;
}
}
类B
public class B implements Ordered {
@Override
public int getOrder() {
return 10;
}
}
应用:
A a = new A();
B b = new B();
OrderComparator comparator = new OrderComparator();
System.out.println(comparator.compare(a, b));//-1 a大为1,b大为-1
List list = new ArrayList<>();
list.add(a);
list.add(b);
//按order值升序排序
list.sort(comparator);
System.out.println(list);//[org.com.zhuyn.Service.A@2f2c9b19, org.com.zhuyn.Service.B@31befd9f]
@Order注解实现方法
Spring提供了OrderComparator的子类:AnnotationAwareOrderComparator,它支持使用@Order来指定order值
类C
@Order(1)
public class C {
}
类D
@Order(10)
public class D {
}
应用
C c = new C();
D d = new D();
AnnotationAwareOrderComparator comparator = new AnnotationAwareOrderComparator();
System.out.println(comparator.compare(c,d));//-1
七、类的元数据
在Spring中需要去解析类的信息,比如类名,类中的方法,类上的注解,这些都可以称为类的元数据。所以Spring中对类的元数据做了抽象,并提供了一些工具类。
1、MetaDataReader(类的元数据读取器)
解析一个类,得到类的所有信息。AnnotatedBeanDefinitionReader 只读取了类的注解而MetaDataReader读取了一个类的所有信息,包括类的注解,类继承了什么,类实现了哪些方法.....等等。
MetaDataReader是一个接口,默认实现类为SimpleMetadataReader。
SimpleMetadataReaderFactory simpleMetadataReaderFactory = new SimpleMetadataReaderFactory();
//构造一个MetaDataReader
MetadataReader metadataReader = simpleMetadataReaderFactory.getMetadataReader("org.com.zhuyn.Service.UserService");
//得到一个ClassMetaData,并获取类名
ClassMetadata classMetadata = metadataReader.getClassMetadata();
System.out.println(classMetadata.getClassName());
//获取接口名字,结果为一个数组
System.out.println(classMetadata.getInterfaceNames()[0]);
//类上注解的信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
for(String annotionMetadata:annotationMetadata.getAnnotationTypes()){
System.out.println(annotionMetadata);
}
八、过滤器
1、excludeFilters
排除类名为UserService的类,就算她上面有@component注解,也不会成为Bean
@ComponentScan(value = "org.com.zhuyn",
excludeFilters = {@ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
classes = UserService.class
)
})
public class AppConfig {
}
2、includeFilters
就算UserService类上没有@Component注解,它也会被扫描成为一个Bean。
@ComponentScan(value = "org.com.zhuyn",
includeFilters = {@ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
classes = UserService.class
)})
public class AppConfig{
}
九、FactoryBean
可以通过这个来自己创建一个Bean
原文地址:https://blog.csdn.net/benxiangsj/article/details/140396788
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!