Spring解决的核心问题
Spring解决的核心问题: 把对象之间的关系用配置来管理
Bean与BeanDefinition
Bean 是Spring的一等公民
在Spring中, 是根据配置, 生成用来描述Bean的BeanDefinition. 类似于Java中描述类的Class.
BeanDefinition的几个重要属性:
创建一个User类
package com.imooc.entity;
public class User {
}
静态工厂类
package com.imooc.entity.factory;
import com.imooc.entity.User;
public class StaticFactory {
public static User getUser() {
return new User();
}
}
实例工厂类
package com.imooc.entity.factory;
import com.imooc.entity.User;
public class UserFactory {
public User getUser() {
return new User();
}
}
<?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="welcomeService" class="com.imooc.service.impl.WelcomeServiceImpl"/>
<!--1. 使用类的无参构造函数创建-->
<bean id = "user1" class="com.imooc.entity.User" scope="singleton" lazy-init="true" primary="true"/>
<!--2.使用静态工厂进行创建-->
<!-- class的值不是写User对象的全路径 而是写静态工厂的全路径 -->
<!-- factory-method的值写要调用的方法 -->
<bean id="user2" class="com.imooc.entity.factory.StaticFactory" factory-method="getUser" scope="singleton" />
<!--3.使用实例工厂进行创建-->
<!--需要先创建factoryBean对象,再通过factoryBean对象进行调用-->
<bean id="userFactory" class="com.imooc.entity.factory.UserFactory" />
<bean id="user3" factory-bean="userFactory" factory-method="getUser" scope="singleton"/>
</beans>
配置文件的解读
代码运行测试
public static void main(String[] args) {
System.out.println("hello world");
String xmlPath = "D:\\coding\\spring-framework-5.2.0.RELEASE\\springdemo\\src\\main\\resources\\spring\\spring-config.xml";
ApplicationContext applicationContext = new FileSystemXmlApplicationContext(xmlPath);
WelcomeService welcomeService = (WelcomeService)applicationContext.getBean("welcomeService");
welcomeService.sayHello("试水Spring框架");
User user1a = (User) applicationContext.getBean("user1");
User user1b = (User) applicationContext.getBean("user1");
System.out.println("无参构造函数创建的对象:"+user1a);
System.out.println("无参构造函数创建的对象:"+user1b);
User user2a = (User) applicationContext.getBean("user2");
User user2b = (User) applicationContext.getBean("user2");
System.out.println("静态工厂创建的对象:"+user2a);
System.out.println("静态工厂创建的对象:"+user2b);
User user3a = (User) applicationContext.getBean("user3");
User user3b = (User) applicationContext.getBean("user3");
System.out.println("实例工厂创建的对象:"+user3a);
System.out.println("实例工厂创建的对象:"+user3b);
}
Spring容器主要流程
BeanDefinition的主要类关系图如下
BeanDefinition
是在spring-beans
模块中的
spring-beans模块存放的是Bean和简单容器相关的接口和类.
BeanDefinition 继承了AttributeAccessor, BeanMetadataElement 这两个接口 .
在Spring中, 某个类继承或实现了某个接口, 也就代表了这个类或者接口有哪些功能.
AttributeAccessor
AttributeAccessor
: 该接口的描述如下, 该接口定义了对任意数据元数据的修改或获取方式.
* Interface defining a generic contract for attaching and accessing metadata
* to/from arbitrary objects.
BeanMetadataElement
BeanMetadataElement 接口, 主要是提供了getSource() 方法. 该方法是用于传输一个可配置的元对象, 主要是返回BeanDefinition 这个对象本身.
Return the configuration source Object for this metadata element (may be null).
AbstractBeanDefinition
AbstractBeanDefinition 抽象类, 实现了BeanDefinition 接口, 里面的方法用于给通用的属性赋值.
其一些方法如下.
在AbstractBeanDefinition 抽象类基础上, 衍生出了如下的一些子类.
RootBeanDefinition
类中有如下的方法. 该方法说明了RootBeanDefinition
类不能作为其他BeanDefinition类的子类 , 但可以作为父类.
@Override public void setParentName(@Nullable String parentName) { if (parentName != null) { throw new IllegalArgumentException("Root bean cannot be changed into a child bean with parent reference"); } }
在DefaultListableBeanFactory 类中有private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) 方法, 使用到了RootBeanDefinition.
可以看到是调用了getMergedLocalBeanDefinition 方法用于合并bean 的.
ChildBeanDefinition
ChildBeanDefinition是一个子类, 不能单独存在, 必须要依赖于一个父的BeanDefinition. ChildBeanDefinition目前已经完全被GenericBeanDefinition 取代.
GenericBeanDefinition
GenericBeanDefinition 是通用的BeanDefinition实现. 是一个Bean文件属性定义类,
GenericBeanDefinition 类有如下的setParentName方法, 该方法可以设置parentName, 不会像RootBeanDefinition去抛异常.
@Override
public void setParentName(@Nullable String parentName) {
this.parentName = parentName;
}
Spring源码解析之 Bean与BeanDefinition详解
原文:https://www.cnblogs.com/year12/p/14828090.html