SpringIoc
Spring IOC 容器 Bean 对象实例化模拟
思路:
定义Bean 工厂接口,提供获取bean方法
定义Bean工厂接口实现类,解析配置文件,实例化Bean对象
实现获取Bean方法
定义 Bean 属性对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package com.xxxx.spring;
public class MyBean {
private String id; private String clazz;
public MyBean() { }
public MyBean(String id, String clazz) { this.id = id; this.clazz = clazz; }
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getClazz() { return clazz; }
public void setClazz(String clazz) { this.clazz = clazz; } }
|
添加 dom4j 坐标依赖
1 2 3 4 5 6 7 8 9 10 11 12
| <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency>
<dependency> <groupId>jaxen</groupId> <artifactId>jaxen</artifactId> <version>1.1.6</version> </dependency>
|
准备自定义配置文件spring.xml
1 2 3 4 5
| <?xml version="1.0" encoding="utf-8" ?> <beans> <bean id="userService" class="com.xxxx.service.UserService"></bean> <bean id="accountService" class="com.xxxx.service.AccountService"></bean> </beans>
|
定义 Bean 工厂接口
1 2 3 4 5 6 7 8 9
| package com.xxxx.spring;
public interface MyFactory { public Object getBean(String id); }
|
定义 Bean 接口的实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
| package com.xxxx.spring;
import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.XPath; import org.dom4j.io.SAXReader; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;
public class MyClassPathXmlApplicationContext implements BeanFactory {
private Map beans = new HashMap(); private List<MyBean> myBeans;
public MyClassPathXmlApplicationContext(String fileName) {
this.parseXml(fileName);
this.instanceBean();
}
private void parseXml(String fileName) { SAXReader reader = new SAXReader(); URL url = this.getClass().getClassLoader().getResource(fileName); try { Document document = reader.read(url); XPath xPath = document.createXPath("beans/bean"); List<Element> list = xPath.selectNodes(document); if (list != null && list.size() > 0) { myBeans = new ArrayList<>(); for(Element el : list) { String id = el.attributeValue("id"); String clazz = el.attributeValue("class"); System.out.println(el.attributeValue("id")); System.out.println(el.attributeValue("class")); MyBean bean = new MyBean(id, clazz); myBeans.add(bean); } } } catch (DocumentException e) { e.printStackTrace(); } }
private void instanceBean() { if (myBeans != null && myBeans.size() > 0) { for (MyBean bean : myBeans){ try { Object object = Class.forName(bean.getClazz()).newInstance(); beans.put(bean.getId(), object); } catch (Exception e) { e.printStackTrace(); } } } }
@Override public Object getBean(String id) { Object object = beans.get(id); return object; } }
|
测试自定义 IOC 容器
创建与配置文件中对应的Bean对象
UserService.java
1 2 3 4 5 6 7 8
| package com.xxxx.service; public class UserService { public void test(){ System.out.println("UserService Test..."); } }
|
AccountService.java
1 2 3 4 5 6 7 8
| package com.xxxx.service;
public class AccountService {
public void test(){ System.out.println("AccountService Test..."); } }
|
2.测试是否可以获取实例化的Bean对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package com.xxxx;
import com.xxxx.spring.MyFactory; import com.xxxx.spring.MyClassPathXmlApplicationContext; import com.xxxx.service.AccountService; import com.xxxx.service.UserService;
public class App { public static void main(String[] args) { MyFactory factory = new MyClassPathXmlApplicationContext("spring.xml"); UserService userService = (UserService) factory.getBean("userService"); userService.test();
UserService userService2 = (UserService) factory.getBean("userService"); System.out.println(userService+"=====" + userService2);
AccountService accountService = (AccountService)factory.getBean("accountService"); accountService.test();
} }
|
Spring 容器在启动的时候 读取xml配置信息,并对配置的 bean 进行实例化(这里模拟的比较简单,仅用于帮助大家理解),同时通过上下文对象提供的 getBean() 方法拿到我们配置的 bean 对象,从而实现外部容器自动化维护并创建 bean 的效果
Spring IOC 容器 Bean 对象实例化
1.构造器实例化
注:通过默认构造器创建 空构造方法必须存在 否则创建失败
- 设置配置文件 spring.xml
1 2 3 4 5 6 7 8 9
| <?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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userService" class="com.xxxx.service.UserService"></bean>
</beans>
|
2.获取实例化对象
1 2 3
| ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml"); UserService userService = (UserService) ac.getBean("userService"); userService.test();
|
2.实例工厂实例化
1.定义工厂类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package com.xxxx.factory;
import com.xxxx.service.UserService;
public class InstanceFactory {
public UserService createUserService() { return new UserService(); } }
|
2.设置配置文件 spring.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="instanceFactory" class="com.xxxx.factory.InstanceFactory"></bean> <bean id="userService" factory-bean="instanceFactory" factory-method="createUserService"></bean>
</beans>
|
3.获取实例化对象
1 2 3
| ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml"); UserService userService = (UserService) ac.getBean("userService"); userService.test();
|
3.静态工厂实例化
1.定义工厂类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package com.xxxx.factory;
import com.xxxx.service.UserService;
public class InstanceFactory {
public UserService createUserService() { return new UserService(); } }
|
2.设置配置文件 spring.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="instanceFactory" class="com.xxxx.factory.InstanceFactory"></bean> <bean id="userService" factory-bean="instanceFactory" factory-method="createUserService"></bean>
</beans>
|
3.获取实例化对象
1 2 3
| ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml"); UserService userService = (UserService) ac.getBean("userService"); userService.test();
|
Spring三种实例化Bean的方式比较
方式一:通过bean的缺省构造函数创建,当各个bean的业务逻辑相互比较独立的时候或者和外界关联较少的时候可以使用。
方式二:利用静态factory方法创建,可以统一管理各个bean的创建,如各个bean在创建之前需要相同的初始化处理,则可用这个factory方法险进行统一的处理等等。
方式三:利用实例化factory方法创建,即将factory方法也作为了业务bean来控制,1可用于集成其他框架的bean创建管理方法,2能够使bean和factory的角色互换。
开发中项目一般使用一种方式实例化bean,项目开发基本采用第一种方式,交给Spring托管,使用时直接拿来使用即可。另外两种了解