ToB企服应用市场:ToB评测及商务社交产业平台

标题: 03Spring底层架构核心概念剖析 [打印本页]

作者: 一给    时间: 2024-7-26 20:07
标题: 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的实现过程
  1.         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
  2.         AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
  3.         beanDefinition.setBeanClass(UserService.class);
  4.         beanDefinition.setScope("prototype");
  5.         //把beanDefinition注册到容器中
  6.         context.registerBeanDefinition("userService",beanDefinition);
  7.         UserService userService = (UserService)context.getBean("userService");
  8.         userService.test();
复制代码
 三、Spring内部的组件

下面的组件在Spring中使用的很少,但是在源码中使用的许多,学习有利于理解源码
1、AnnotatedBeanDefinitionReader
可以直接把某个类转换为BeanDefinition,并读取剖析类的注解。就是BeanDefiniton读取器。把读到的BeanDefinition存到容器中
  1.         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
  2.         AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(context);
  3.         //将UserService.class解析为BeanDefinition
  4.         annotatedBeanDefinitionReader.register(UserService.class);
  5.         System.out.println(context.getBean("userService"));
复制代码
2、XmlBeanDefinitionReader
可以剖析<bean/>标签
  1.           AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
  2.           XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context);
  3.           xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");
复制代码
3、ClassPathBeanDefinitionScanner
扫描器,和BeanDefinitionReader类似,对某个包路径就行扫描,对扫描的类进行剖析,假如存在@Component注解,就会把这个类剖析为一个BeanDefinition
  1.        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
  2.         context.refresh();
  3.         ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
  4.         int i = scanner.scan("org.com.zhuyn");
  5.         System.out.println(context.getBean("userService"));
复制代码
四、ApplicationContext与BeanFactory

ApplicationContext继承了BeanFactory,除此之外还继承了别的
   ApplicationEnventPublisher:事件发布器
  EnvironmentCapable:获取环境变量的功能
  MessageSource:进行国际化的功能
  ResourcepatternResolver:剖析某些资源的功能
  因此,当我们使用applicationContext.getBean("xxx")的时候,本质上是使用的DefaultListableBeanFactory来获取的。
1、ResourcepatternResolver
(1)拿文件资源
  1.         ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
  2.         Resource resource = context.getResource("file://C:\\Usersxxxxxxxxx"");
  3.         System.out.println(resource.contentLength());
复制代码
(2)拿url
  1.         ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
  2.         Resource resource = context.getResource("https://www.baidu.com");
  3.         System.out.println(resource.contentLength());
  4.         System.out.println(resource.getURL());
复制代码
这里的Resource可以拿许多种资源。
2、ApplicationEnventPublisher
在工作当中可以直接界说一个事件发布器、
  1. @Component
  2. public class UserService {
  3.     private ApplicationEventPublisher applicationEventPublisher;
  4.    
  5. }
复制代码
也可以使用applicationContext自带的事件发布器
  1. @Component
  2. public class UserService {
  3.    @Autowired
  4.     private ApplicationContext context;
  5.     public void test(){
  6.         context.publishEvent("hello");
  7.         System.out.println("test");
  8.     }
  9. }
复制代码
事件监听器
  1. @ComponentScan("org.com.zhuyn")
  2. public class AppConfig {
  3.     @Bean
  4.     public ApplicationListener applicationListener(){
  5.         return new ApplicationListener() {
  6.             @Override
  7.             public void onApplicationEvent(ApplicationEvent applicationEvent) {
  8.                 System.out.println("发布了一个事件"+applicationEvent);
  9.             }
  10.         };
  11.     }
  12. }
复制代码
五、范例转化

1、PropertyEditor
把字符串转换成user对象。
范例转换器
  1. public class StringToUserPropertyEditor extends PropertyEditorSupport implements PropertyEditor {
  2.     @Override
  3.     public void setAsText(String text) throws IllegalArgumentException {
  4.         User user = new User();
  5.         user.setName(text);
  6.         this.setValue(user);
  7.     }
  8. }
复制代码
范例转换器的使用
  1.         ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
  2.         StringToUserPropertyEditor propertyEditor = new StringToUserPropertyEditor();
  3.         propertyEditor.setAsText("xiaoming");
  4.         User user = (User) propertyEditor.getValue();
  5.         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
  1. public class A implements Ordered {
  2.     @Override
  3.     public int getOrder() {
  4.         return 1;
  5.     }
  6. }
复制代码
类B
  1. public class B implements Ordered {
  2.     @Override
  3.     public int getOrder() {
  4.         return 10;
  5.     }
  6. }
复制代码
应用:
  1.         A a = new A();
  2.         B b = new B();
  3.         OrderComparator comparator = new OrderComparator();
  4.         System.out.println(comparator.compare(a, b));//-1 a大为1,b大为-1
  5.         List list = new ArrayList<>();
  6.         list.add(a);
  7.         list.add(b);
  8.         //按order值升序排序
  9.         list.sort(comparator);
  10.         System.out.println(list);//[org.com.zhuyn.Service.A@2f2c9b19, org.com.zhuyn.Service.B@31befd9f]
复制代码
@Order注解实现方法
Spring提供了OrderComparator的子类:AnnotationAwareOrderComparator,它支持使用@Order来指定order值
类C
  1. @Order(1)
  2. public class C {
  3. }
复制代码
类D
  1. @Order(10)
  2. public class D {
  3. }
复制代码
应用
  1.         C c = new C();
  2.         D d = new D();
  3.         AnnotationAwareOrderComparator comparator = new AnnotationAwareOrderComparator();
  4.         System.out.println(comparator.compare(c,d));//-1
复制代码
七、类的元数据

在Spring中须要去剖析类的信息,比如类名,类中的方法,类上的注解,这些都可以称为类的元数据。所以Spring中对类的元数据做了抽象,并提供了一些工具类。
1、MetaDataReader(类的元数据读取器)
剖析一个类,得到类的所有信息。AnnotatedBeanDefinitionReader 只读取了类的注解而MetaDataReader读取了一个类的所有信息,包罗类的注解,类继承了什么,类实现了哪些方法.....等等。
MetaDataReader是一个接口,默认实现类为SimpleMetadataReader。
  1.         SimpleMetadataReaderFactory simpleMetadataReaderFactory = new SimpleMetadataReaderFactory();
  2.         //构造一个MetaDataReader
  3.         MetadataReader metadataReader = simpleMetadataReaderFactory.getMetadataReader("org.com.zhuyn.Service.UserService");
  4.         //得到一个ClassMetaData,并获取类名
  5.         ClassMetadata classMetadata = metadataReader.getClassMetadata();
  6.         System.out.println(classMetadata.getClassName());
  7.         //获取接口名字,结果为一个数组
  8.         System.out.println(classMetadata.getInterfaceNames()[0]);
  9.         //类上注解的信息
  10.         AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
  11.         for(String annotionMetadata:annotationMetadata.getAnnotationTypes()){
  12.             System.out.println(annotionMetadata);
  13.         }
复制代码
八、过滤器

1、excludeFilters
排除类名为UserService的类,就算她上面有@component注解,也不会成为Bean
  1. @ComponentScan(value = "org.com.zhuyn",
  2. excludeFilters = {@ComponentScan.Filter(
  3.         type = FilterType.ASSIGNABLE_TYPE,
  4.         classes = UserService.class
  5. )
  6. })
  7. public class AppConfig {
  8.    
  9. }
复制代码
2、includeFilters
就算UserService类上没有@Component注解,它也会被扫描成为一个Bean。
  1. @ComponentScan(value = "org.com.zhuyn",
  2. includeFilters = {@ComponentScan.Filter(
  3.         type = FilterType.ASSIGNABLE_TYPE,
  4.         classes = UserService.class
  5. )})
  6. public class AppConfig{
  7. }
复制代码
九、FactoryBean
可以通过这个来自己创建一个Bean


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4