spring之BeanDefinition
- 编程式定义Bean示例代码
- BeanDefinitionReader
- AnnotatedBeanDefinitionReader
- XmlBeanDefinitionReader
- ClassPathBeanDefinitionScanner
BeanDefinition是一个接口,用来表示Bean定义。
BeanDefinition中存在很多属性用来描述一个Bean的特点。比如:
-
class,表示Bean类型
-
scope,表示Bean作用域,单例或原型等
-
lazyInit:表示Bean是否是懒加载
-
initMethodName:表示Bean初始化时要执行的方法
-
destroyMethodName:表示Bean销毁时要执行的方法
-
primary:表示相同bean存在时,那个是主要的bean
-
abstractFlag:表示是否是抽象类
-
。。。。。。
在Spring中,我们经常会通过以下几种方式来定义Bean:
- <bean/>
- @Bean
- @Component(@Service,@Controller)
这些,我们可以称之申明式定义Bean。
和申明式事务、编程式事务类似,通过申明式方式所定义的Bean,最终都会被Spring解析为对应的BeanDefinition对象,并放入Spring容器中。
编程式定义Bean示例代码
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.20</version>
</dependency>
public class AppConfig {
}
public class User {
public User() {
System.out.println("无参构造");
}
public void init() {
System.out.println("初始化init方法");
}
}
public static void main(String[] args) {
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(User.class);
beanDefinition.setScope("prototype");
beanDefinition.setInitMethodName("init");
beanDefinition.setLazyInit(true);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
context.registerBeanDefinition("user", beanDefinition);
System.out.println(context.getBean("user"));
}
BeanDefinitionReader
BeanDefinitionReader是spring源码中提供的BeanDefinition读取器,这些BeanDefinitionReader在spring底层源码中使用的非常多,相当于spring的基础设施。
AnnotatedBeanDefinitionReader
可以直接把某个类转换为BeanDefinition,并且会解析该类上的注解,比如:@Conditional,@Scope、@Lazy、@Primary、@DependsOn、@Role、@Description等。
示例代码
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.core.annotation.Order;
@Scope(BeanDefinition.SCOPE_SINGLETON)
@Order(0)
@Lazy
@Primary
public class User {
public User() {
System.out.println("无参构造");
}
public void init() {
System.out.println("初始化init方法");
}
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(context);
annotatedBeanDefinitionReader.register(User.class);
BeanDefinition beanDefinition = annotatedBeanDefinitionReader.getRegistry().getBeanDefinition("user");
System.out.println(beanDefinition.getScope());
System.out.println(beanDefinition.isPrimary());
System.out.println(beanDefinition.isSingleton());
System.out.println(context.getBean("user"));
}
XmlBeanDefinitionReader
可以解析<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="top.mingempty.spring.service.User" scope="singleton" lazy-init="true" name="user">
</bean>
</beans>
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context);
int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");
System.out.println(i);
BeanDefinition beanDefinition = context.getBeanDefinition("user");
System.out.println(beanDefinition.getScope());
System.out.println(beanDefinition.isPrimary());
System.out.println(beanDefinition.isSingleton());
System.out.println(context.getBean("user"));
}
ClassPathBeanDefinitionScanner
ClassPathBeanDefinitionScanner是扫描器。可以扫描指定包路径的类,并对扫描的类进行解析。扫描到的类上如果存在@Component注解,那么就会把这个类解析为一个BeanDefinition。
示例代码
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@Order(0)
@Lazy
@Primary
@Component
public class UserService {
public void test() {
System.out.println("demo");
}
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.refresh();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.scan("top.mingempty.spring.service");
BeanDefinition beanDefinition = context.getBeanDefinition("userService");
System.out.println(beanDefinition.getScope());
System.out.println(beanDefinition.isPrimary());
System.out.println(beanDefinition.isSingleton());
System.out.println(context.getBean("userService"));
System.out.println(context.getBean("userService"));
}