SpringIOC随笔(四)-Bean上

it2023-08-11  72

SpringIOC随笔(四)-Bean上

Bean的创建

无参构造方法创建

这个不需要再解释了吧。

静态工厂方式

public class StaticFactoryBeanDemo { public static StaticFactoryBeanDemo createInstance(){ System.out.println("createInstance()方法调用!"); return new StaticFactoryBeanDemo(); } public void service(){ System.out.println("Service方法调用!"); } } <?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="staticFactoryBeanDemo" class="com.fxyh.bean.StaticFactoryBeanDemo" factory-method="createInstance"/> </beans> public class StaticFactoryBeanTest { private ApplicationContext context; private StaticFactoryBeanDemo staticFactoryBeanDemo; @Before public void setUp() throws Exception { this.context = new ClassPathXmlApplicationContext("classpath*:applicationContext-bean.xml"); this.staticFactoryBeanDemo = this.context.getBean(StaticFactoryBeanDemo.class); } @Test public void test() { staticFactoryBeanDemo.service(); } } 这里factory-method="createInstance"是调用的com.fxyh.bean.StaticFactoryBeanDemo静态方法,在静态方法中创建的一个对象然后返回,这就是静态工厂的方式。

工厂实例方式

public class FactoryInstance { public FactoryInstanceDemo createFactoryInstanceDemo(){ System.out.println("createFactoryInstanceDemo()调用!"); return new FactoryInstanceDemo(); } } public class FactoryInstanceDemo { public void service(){ System.out.println("FactoryInstanceDemo service()调用!"); } } <?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="factoryInstance" class="com.fxyh.bean.FactoryInstance" /> <bean id="factoryInstanceDemo" class="com.fxyh.bean.FactoryInstanceDemo" factory-bean="factoryInstance" factory-method="createFactoryInstanceDemo"/> </beans> public class FactoryInstanceTest { private ApplicationContext context; private FactoryInstanceDemo factoryInstanceDemo; @Before public void setUp() throws Exception { this.context = new ClassPathXmlApplicationContext("classpath*:applicationContext-bean.xml"); this.factoryInstanceDemo = this.context.getBean(FactoryInstanceDemo.class); } @Test public void test(){ factoryInstanceDemo.service(); } } 这里先创建了factoryInstance,然后在调用factoryInstance的createFactoryInstanceDemo方法创建了factoryInstanceDemo,这里的前提是要创建了factoryInstanceBean。

Bean的创建时机

lazy-init

default:默认是false

false:创建Bean容器时立即创建bean。

true:创建Bean容器时不会创建这个bean,等我们调用getBean的时候才会创建这个Bean。

全局配置:

<?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" default-lazy-init="true"> </beans>

局部配置:

<bean id="lazyInitDemo1" class="com.fxyh.bean.LazyInitDemo1" lazy-init="default"> <property name="id" value="1"/> <property name="name" value="zhangsan"/> </bean> <bean id="lazyInitDemo2" class="com.fxyh.bean.LazyInitDemo2" lazy-init="false"> <property name="id" value="2"/> <property name="name" value="lisi"/> </bean> <bean id="lazyInitDemo3" class="com.fxyh.bean.LazyInitDemo3" lazy-init="true"> <property name="id" value="3"/> <property name="name" value="wangwu"/> </bean>

如果全局配置了,局部也配置了,除了局部配置的是default,true和false全部使用局部配置,default则按全局的配置,如果全局没有配置则是默认false。

测试用例

public class LazyInitDemo1 { public LazyInitDemo1() { System.out.println("LazyInitDemo1()构造方法"); } private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "LazyInitDemo1{" + "id=" + id + ", name='" + name + '\'' + '}'; } } public class LazyInitDemo2 { public LazyInitDemo2() { System.out.println("LazyInitDemo2()构造方法"); } private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "LazyInitDemo2{" + "id=" + id + ", name='" + name + '\'' + '}'; } } public class LazyInitDemo3 { public LazyInitDemo3() { System.out.println("LazyInitDemo3()构造方法"); } private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "LazyInitDemo3{" + "id=" + id + ", name='" + name + '\'' + '}'; } } public class LazyInitDemoTest { private ApplicationContext context; private LazyInitDemo1 lazyInitDemo1; private LazyInitDemo2 lazyInitDemo2; private LazyInitDemo3 lazyInitDemo3; @Before public void setUp() throws Exception { this.context = new ClassPathXmlApplicationContext("classpath*:applicationContext-lazy.xml"); this.lazyInitDemo1 = this.context.getBean(LazyInitDemo1.class);//打断点 this.lazyInitDemo2 = this.context.getBean(LazyInitDemo2.class);//打断点 this.lazyInitDemo3 = this.context.getBean(LazyInitDemo3.class);//打断点 } @Test public void test(){ System.out.println(lazyInitDemo1); System.out.println(lazyInitDemo2); System.out.println(lazyInitDemo3); } }

测试的时候在测试用例getBean的地方打断点,然后dbug就能发现哪些是懒加载,哪些是get的时候才加载。

Bean的作用域

scope

singleton:单例。每次调用getBean()获取到的Bean是同一个Bean。默认为单例。

prototype:原型。每次调用getBean()获取到的Bean是不同的Bean。

request:暂不介绍

session:暂不介绍

global session:暂不介绍

<?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="scopePrototype" class="com.fxyh.bean.ScopePrototype" scope="prototype" /> <bean id="scopeSingleton" class="com.fxyh.bean.ScopeSingleton"/> </beans> public class ScopeTest { private ApplicationContext context; private ScopeSingleton scopeSingleton1; private ScopeSingleton scopeSingleton2; private ScopePrototype scopePrototype1; private ScopePrototype scopePrototype2; @Before public void setUp() throws Exception { this.context = new ClassPathXmlApplicationContext("classpath*:applicationContext-scope.xml"); this.scopeSingleton1 = this.context.getBean(ScopeSingleton.class); this.scopeSingleton2 = this.context.getBean(ScopeSingleton.class); this.scopePrototype1 = this.context.getBean(ScopePrototype.class); this.scopePrototype2 = this.context.getBean(ScopePrototype.class); } @Test public void test(){ System.out.println(scopeSingleton1 == scopeSingleton2);//true System.out.println(scopePrototype1 == scopePrototype2);//false } }

当lazy-init遇到原型的时候,lazy-init="false"将会无效,个人理解:因为原型的时候,每次调用getBean都是不一样的bean,所以没有必要在容器初始化的时候就加载出来吧。

最新回复(0)