一、BeanDefinition含义(理解描述)
BeanDefinition表示Spring容器中Bean的定义,在BeanDefinition类中存在很多属性用来描述一个Bean的定义。
注释:Spring容器中Bean的定义,就是通过xml配置、扫描注解把需要纳入到Spring容器中的类,通过BeanDefinition来定义。
二、BeanDefinition类中属性:
beanClass,表示Bean类型
scope,表示Bean作用域,单例或原型等
lazyInit:表示Bean是否是懒加载
initMethodName:表示Bean初始化时要执行的方法
destroyMethodName:表示Bean销毁时要执行的方法
等等...
基于以上内容,我们可以理解为BeanDefinition对象就是一个Bean的元数据,为什么Bean的元数据需要一个BeanDefinition来存储元数据呢?
因为一个被Spring容器管理的Bean不仅仅是放到Spring容器中,而是要应对不同场景,比如有单例和多例的Bean,有的Bean需要懒加载,有的Bean在被注入的时候需要执行初始化方法等等,而这些都需要额外来记录,单单靠Bean对象所对应的类自己是不行的,Bean对象所对应的类也就是Java类,他是相对于Spring更底层的东西,属于Jvm层,而Bean是属于Spring体系,Spring体系就需要想办法来记录这个Bean的信息,所以需要BeanDefinition对象保存Bean的元数据。
三、定义Bean的方式
3.1 声明式定义Bean
xml配置【<bean/>】
方法注解【@Bean】
类上注解【@Component(@Service,@Controller)】
3.2 编程式定义Bean
基础代码:
Config.java
package cn.edkso.coreConcept;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("cn.edkso.coreConcept")
public class Config {
}
TestService.java
package cn.edkso.coreConcept;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
//@Component
//@Controller
@Service
public class TestService {
public TestService() {
System.out.println("TestService被创建了!");
}
public void init(){
System.out.println("TestService执行初始化方法!");
}
}
编程式定义Bean代码:
/**
* 编程式定义BeanDefinition
*/
private static void test1(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(TestService.class);
beanDefinition.setScope("prototype");
// beanDefinition.setScope("singleton");
beanDefinition.setLazyInit(false);
beanDefinition.setInitMethodName("init");
context.registerBeanDefinition("testService", beanDefinition);
System.out.println(context.getBean("testService"));
System.out.println(context.getBean("testService"));
}
注释:编程式方式定义的Bean方式和声明式方式所定义的Bean,最终都会被Spring解析为对应的BeanDefinition对象,并放入Spring容器中。
四、BeanDefinition读取器
在Spring源码中提供了几种BeanDefinition读取器 (BeanDefinitionReader),这些BeanDefinitionReader在我们使用Spring时用得少,但在Spring 源码中用得多,相当于Spring源码的基础设施。
4.1 AnnotatedBeanDefinitionReader
AnnotatedBeanDefinitionReader Bean读取器
– 1.通过该Bean读取器,可以把一个类直接读取成BeanDefinition并进行注册;
在读取过程中,会检测指定类中的各种注解,并根据注解做相应的处理。
– 3.new AnnotationConfigApplicationContext(Config.class)
内部源码就是通过AnnotatedBeanDefinitionReader读取的Config配置类
/**
* AnnotatedBeanDefinitionReader Bean读取器
* -- 1.通过该Bean读取器,可以把一个类直接读取成BeanDefinition并进行注册;
* 在读取过程中,会检测指定类中的各种注解,并根据注解做相应的处理。
* -- 3.new AnnotationConfigApplicationContext(Config.class)
* 内部源码就是通过AnnotatedBeanDefinitionReader读取的Config配置类
*/
private static void test2(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
AnnotatedBeanDefinitionReader abd = new AnnotatedBeanDefinitionReader(context);
abd.register(TestService.class);
System.out.println(context.getBean("testService"));
}
4.2 XmlBeanDefinitionReader
xml配置Bean文件:
spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="testService" class="cn.edkso.coreConcept.TestService"></bean>
</beans>
XmlBeanDefinitionReader Bean读取器:
XmlBeanDefinitionReader Bean读取器
– 1.在xml文件中配置的bean可以通过此读取器读取,并进行注册。
– 2.在早期Spring版本中,大多数都是通过xml来配置Bean,这样做的缺点是配置文件太多,并且耦合度高
/**
* XmlBeanDefinitionReader Bean读取器
* -- 1.在xml文件中配置的bean可以通过此读取器读取,并进行注册。
* -- 2.在早期Spring版本中,大多数都是通过xml来配置Bean,这样做的缺点是配置文件太多,并且耦合度高
*/
private static void test3(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
XmlBeanDefinitionReader xbd = new XmlBeanDefinitionReader(context);
xbd.loadBeanDefinitions("spring.xml");
System.out.println(context.getBean("testService"));
}
4.3 ClassPathBeanDefinitionScanner
ClassPathBeanDefinitionScanner Bean读取器(扫描器)
– 1.扫描Bean读取器,会扫描指定包路径下的Bean进行读取,并进行注册。
– 2.在指定包下,配置@Service、@Component、@Controller 等注解的才是要纳入Spring进行管理的Bean
/**
* ClassPathBeanDefinitionScanner Bean读取器(扫描器)
* -- 1.扫描Bean读取器,会扫描指定包路径下的Bean进行读取,并进行注册。
* -- 2.在指定包下,配置@Service、@Component、@Controller 等注解的才是要纳入Spring进行管理的Bean
*/
private static void test4(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
ClassPathBeanDefinitionScanner cpbd = new ClassPathBeanDefinitionScanner(context);
cpbd.scan("cn.edkso.coreConcept");
System.out.println(context.getBean("testService"));
}
版权声明:
作者:十下
链接:https://blog.edkso.cn/?p=1027
来源:十下博客
文章版权归作者所有,未经允许请勿转载。