马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
为了感谢罕哥对我工作的资助,特此记录放学习过程,等待成为和罕哥一样优秀的人
时间: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
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |