BeanFactory,以Factory结尾,表示它是一个工厂类(接口), 它负责生产和管理bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
BeanFactory只是个接口,并不是IOC容器的具体实现,但是Spring容器给出了很多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,其中XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。
原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。ApplicationContext接口,它由BeanFactory接口派生而来。现在一般使用ApplicationnContext,其不但包含了BeanFactory的作用,同时还进行更多的扩展
Note:BeanFactory和ApplicationContext创建Bean的区别
BeanFactory | 延时加载,在使用到某个Bean时才会进行实例化Bean |
ApplicationConetxt | 在ApplicationContext对象创建时,会立即实例化单例Bean以及其依赖 |
- "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="userDao" class="com.lb.springioc.dao.UserDaoImpl">bean>
-
- <bean id="userService" class="com.lb.springioc.service.UserServiceImpl">
- <property name="userDao" ref="userDao">property>
- bean>
- beans>
BeanDefinition | 对应配置文件中的 |
BeanDefinitionReader | 读取配置文件所有的BeanDefinition |
BeanDefinitionRegistry | 将Reader读取到的BeanDefinition放在容器中 |
BeanDefinitionHolder就是持有对bean标签读取到的信息的对象
- <dependency>
- <groupId>org.projectlombokgroupId>
- <artifactId>lombokartifactId>
- <version>1.16.10version>
- dependency>
-
- <dependency>
- <groupId>dom4jgroupId>
- <artifactId>dom4jartifactId>
- <version>1.6.1version>
- dependency>
- @Data
- public class BeanDefinition {
- private String id;
- private String className;
- private PropertyValues propertyValues;
-
- public BeanDefinition() {
- propertyValues = new PropertyValues();
- }
- }
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- public class PropertyValue {
- private String name;
- private String ref;
- private String value;
- }
- public class PropertyValues implements Iterable
{ - private List
list; -
- public PropertyValues() {
- list = new ArrayList<>();
- }
-
- public PropertyValues add(PropertyValue propertyValue) {
- for (int i = 0; i < list.size(); i++) {
- PropertyValue value = list.get(i);
- if (value.getName().equals(propertyValue.getName())) {
- list.set(i, propertyValue);
- return this;
- }
- }
- list.add(propertyValue);
- return this;
- }
-
- public PropertyValue[] getPropertyValues() {
- return list.toArray(new PropertyValue[0]);
- }
-
- public PropertyValue geTPropertyValue(String name) {
- for (int i = 0; i < list.size(); i++) {
- PropertyValue value = list.get(i);
- if (value.getName().equals(name)) {
- return value;
- }
- }
- return null;
- }
-
- public boolean isEmpty() {
- return list.isEmpty();
- }
-
- @Override
- public Iterator
iterator() { - return list.iterator();
- }
- }
- public interface BeanDefinitionReader {
- BeanDefinitionRegistry getRegistry();
-
- void loadResource(String location) throws Exception;
- }
- public class XmlBeanDefinitionReader implements BeanDefinitionReader {
-
- private BeanDefinitionRegistry registry;
-
- public XmlBeanDefinitionReader() {
- registry = new SimpleBeanDefinitionRegistry();
- }
-
- @Override
- public BeanDefinitionRegistry getRegistry() {
- return registry;
- }
-
- @Override
- public void loadResource(String location) throws Exception {
- SAXReader reader = new SAXReader();
- InputStream inputStream = XmlBeanDefinitionReader.class.getClassLoader().getResourceAsStream(location);
- Document document = reader.read(inputStream);
- Element rootElement = document.getRootElement();
- List
beans = rootElement.elements("bean"); -
- for (Element bean : beans) {
- BeanDefinition beanDefinition = new BeanDefinition();
- String id = bean.attributeValue("id");
- beanDefinition.setId(id);
- beanDefinition.setClassName(bean.attributeValue("class"));
- PropertyValues values = new PropertyValues();
- List
properties = bean.elements("property"); - for (Element property : properties) {
- PropertyValue value = new PropertyValue();
- value.setName(property.attributeValue("name"));
- value.setRef(property.attributeValue("ref"));
- value.setValue(property.attributeValue("value"));
- values.add(value);
- }
- beanDefinition.setPropertyValues(values);
- registry.registerBeanDefinition(id, beanDefinition);
- }
- }
- }
- public interface BeanDefinitionRegistry {
- void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);
-
- void removeBeanDefinition(String beanName) throws Exception;
-
- BeanDefinition getBeanDefinition(String beanName);
-
- boolean containsBeanDefinition(String beanName);
-
- String[] getBeanDefinitionNames();
-
- int getBeanDefinitionCount();
- }
-
- public class SimpleBeanDefinitionRegistry implements BeanDefinitionRegistry {
- private Map
map = new HashMap(); -
-
- @Override
- public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
- map.put(beanName, beanDefinition);
- }
-
- @Override
- public void removeBeanDefinition(String beanName) throws Exception {
- map.remove(beanName);
- }
-
- @Override
- public BeanDefinition getBeanDefinition(String beanName) {
- return map.get(beanName);
- }
-
- @Override
- public boolean containsBeanDefinition(String beanName) {
- return map.containsKey(beanName);
- }
-
- @Override
- public String[] getBeanDefinitionNames() {
- return map.keySet().toArray(new String[0]);
- }
-
- @Override
- public int getBeanDefinitionCount() {
- return map.size();
- }
- }
- /**
- * 提供BeanFactory的主要功能获取Bean
- */
- public interface BeanFactory {
-
- Object getBean(String beanName) throws Exception;
-
-
T getBean(String beanName, Class extends T> clazz) throws Exception; - }
-
- /**
- * 所有的子类对bean的创建都是非延时的
- */
- public interface ApplicationContext extends BeanFactory {
- /**
- * 加载配置文件,并创建对象
- * @throws Exception
- */
- void refresh() throws Exception;
- }
-
- public abstract class AbstractApplicationContext implements ApplicationContext {
- protected Map
singletonMaps = new HashMap<>(); -
- protected BeanDefinitionReader beanDefinitionReader;
-
- protected String configLocation;
-
- @Override
- public void refresh() throws Exception {
- beanDefinitionReader.loadResource(configLocation);
-
- //初始化所有的bean
- initializationBean();
- }
-
- private void initializationBean() throws Exception {
- BeanDefinitionRegistry registry = beanDefinitionReader.getRegistry();
- String[] beanDefinitionNames = registry.getBeanDefinitionNames();
- for (String beanDefinitionName : beanDefinitionNames) {
- BeanDefinition beanDefinition = registry.getBeanDefinition(beanDefinitionName);
- getBean(beanDefinition.getId());
- }
- }
- }
-
- public class ClassPathXmlApplicationContext extends AbstractApplicationContext {
-
- public ClassPathXmlApplicationContext(String location) {
- this.configLocation = location;
- this.beanDefinitionReader = new XmlBeanDefinitionReader();
-
- try {
- refresh();
- } catch (Exception e) {
-
- }
- }
-
- @Override
- public Object getBean(String beanName) throws Exception {
- Object obj = singletonMaps.get(beanName);
- if (obj != null) {
- return obj;
- }
- BeanDefinitionRegistry registry = beanDefinitionReader.getRegistry();
- BeanDefinition beanDefinition = registry.getBeanDefinition(beanName);
- String clazzName = beanDefinition.getClassName();
- Class> clazz = Class.forName(clazzName);
- Object bean = clazz.newInstance();
-
- PropertyValues propertyValues = beanDefinition.getPropertyValues();
- for (PropertyValue propertyValue : propertyValues) {
- //拼接set方法
- String name = propertyValue.getName();
- String setMethodName = StrUtil.filedName2SetMethodName(name);
- Method[] methods = clazz.getMethods();
- Method method = null;
- for (Method m : methods){
- if (m.getName().equals(setMethodName)){
- method = m;
- break;
- }
- }
- //反射创建对象
- String refStr = propertyValue.getRef();
- if (null != refStr && !"".equals(refStr)) {
- Object refObj = getBean(refStr);
- method.invoke(bean, refObj);
- }
- //value是赋值的
- String value = propertyValue.getValue();
- if (null != value && !"".equals(value)) {
- method.invoke(bean, value);
- }
- }
- singletonMaps.put(beanName, bean);
- return bean;
- }
-
- @Override
- public
T getBean(String beanName, Class extends T> clazz) throws Exception { - Object obj = getBean(beanName);
- if (obj == null) return null;
- return clazz.cast(obj);
- }
- }
将上面的项目打包,测试项目引入其依赖
- <dependency>
- <groupId>com.testgroupId>
- <artifactId>mySpringartifactId>
- <version>0.0.1-SNAPSHOTversion>
- dependency>
测试代码:
applicationContext.xml
- "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="userDao" class="springioc.dao.UserDaoImpl">bean>
-
- <bean id="userService" class="springioc.service.UserServiceImpl">
- <property name="userDao" ref="userDao">property>
- bean>
- beans>
- import com.lb.context.ClassPathXmlApplicationContext;
- import springioc.dao.UserDao;
- import springioc.service.UserService;
-
- public class UserController {
- public static void main(String[] args) throws Exception{
- ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
- UserDao userDao = classPathXmlApplicationContext.getBean("userDao", UserDao.class);
- UserService userService = classPathXmlApplicationContext.getBean("userService", UserService.class);
- System.out.println(userDao);
- System.out.println(userService);
-
- userService.add();
- }
- }
测试结果: