一给 发表于 2024-7-26 20:07:48

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);// @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());
      //类上注解的信息
      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企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 03Spring底层架构核心概念剖析