Day2 Spring初识(二)
Bean的实例化
bean实例化方式有3种:默认构造、静态工厂、实例工厂
默认构造
调用无参构造, 属性+setter
User.java
package entity; public class User { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User [id=" + id + ", name=" + name + "]"; } }
ApplicatitonContext.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"> <!-- 1.默认调用无参构造 属性+setter name:真实赋值使用setter方法 scope:作用域 --> <bean id="user" class="entity.User"> <property name="id" value="1"></property> <property name="name" value="zs"></property> </bean> </beans>
Test.java
package test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import entity.User; public class Test { @org.junit.Test public void test() { ApplicationContext context = new ClassPathXmlApplicationContext("ApplicatitonContext.xml"); User user = context.getBean("user",User.class); System.out.println(user); } }
运行结果
二月 01, 2018 8:19:43 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2a33fae0: startup date [Thu Feb 01 20:19:43 CST 2018]; root of context hierarchy 二月 01, 2018 8:19:44 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [ApplicatitonContext.xml] User [id=1, name=zs]
调用有参构造 属性+有参构造
User.java
package entity; public class User { private int id; private String name; public User(int id, String name) { super(); this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User [id=" + id + ", name=" + name + "]"; } }
ApplicatitonContext.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"> <!-- 2.调用有参构造 属性+有参构造 constructor-arg: name:属性名称 value:简单类型的值 ref:引用 index:参数的索引 type:参数的类型 --> <bean id="user" class="entity.User"> <constructor-arg name="id" value="1" ></constructor-arg> <constructor-arg name="name" value="lisi"></constructor-arg> <!-- <constructor-arg index="0" type="int" value="1"></constructor-arg> <constructor-arg index="1" value="zs"></constructor-arg> --> </bean> </beans>
Test.java
package test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import entity.User; public class Test { @org.junit.Test public void test() { ApplicationContext context = new ClassPathXmlApplicationContext("ApplicatitonContext.xml"); User user = context.getBean("user",User.class); System.out.println(user); } }
运行结果
二月 01, 2018 8:23:39 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2a33fae0: startup date [Thu Feb 01 20:23:39 CST 2018]; root of context hierarchy 二月 01, 2018 8:23:39 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [ApplicatitonContext.xml] User [id=1, name=lisi]
静态工厂
User.java
package entity; public class User { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User [id=" + id + ", name=" + name + "]"; } }
StaticFactory.java
package factory; import entity.User; public class StaticFactory { public static User createUser() { return new User(); } }
ApplicatitonContext.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="factory.StaticFactory" factory-method="createUser"></bean> </beans>
Test.java
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import entity.User;
public class Test {
@org.junit.Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("ApplicatitonContext.xml");
User user = context.getBean("user",User.class);
System.out.println(user);
}
}
运行结果
二月 01, 2018 8:28:44 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2a33fae0: startup date [Thu Feb 01 20:28:44 CST 2018]; root of context hierarchy
二月 01, 2018 8:28:44 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [ApplicatitonContext.xml]
User [id=0, name=null]
动态工厂
User.java
package entity; public class User { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User [id=" + id + ", name=" + name + "]"; } }
InstanceFactory.java
package factory; import entity.User; public class InstanceFactory { public User createUser(){ return new User(); } }
ApplicatitonContext.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"> <!-- 3.实例工厂 --> <bean id="factory" class="factory.InstanceFactory"></bean> <bean id="user" factory-bean="factory" factory-method="createUser"></bean> </beans>
Test.java
package test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import entity.User; public class Test { @org.junit.Test public void test() { ApplicationContext context = new ClassPathXmlApplicationContext("ApplicatitonContext.xml"); User user = context.getBean("user",User.class); System.out.println(user); } }
运行结果
二月 01, 2018 8:32:59 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2a33fae0: startup date [Thu Feb 01 20:32:59 CST 2018]; root of context hierarchy 二月 01, 2018 8:32:59 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [ApplicatitonContext.xml] User [id=0, name=null]
Bean的作用域
- singleton:(单实例模式)spring容器只会存在一个共享的bean实例,并且所有针对该bean的请求只会返回同一个bean实例。
- propertype(no-singleton):对每一次针对该bean的请求都会生成一个新的bean实例。 相当于java中的new 操作。定义为propertype的bean其生命周期很长,不易回收,通常要额外的处理。
- request:针对每一次的http请求都会产生一个新的bean实例,Bean仅在当前的http request范围内有效
- session:针对每一次的http请求都会产生一个新的bean实例,Bean仅在当前的http session范围内有效
Bean的声明周期
图示说明
初始化方法和销毁方法
User.java
package entity; public class User { private int id; private String name; public void init() { System.out.println("初始化"); } public void destory() { System.out.println("销毁"); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User [id=" + id + ", name=" + name + "]"; } }
ApplicatitonContext.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"> <!-- 1.默认调用无参构造 属性+setter name:真实赋值使用setter方法 scope:作用域 --> <bean id="user" class="entity.User" init-method="init" destroy-method="destory"> <property name="id" value="1"></property> <property name="name" value="zs"></property> </bean> </beans>
Test.java
package test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import entity.User; public class Test { @org.junit.Test public void test() { ApplicationContext context = new ClassPathXmlApplicationContext("ApplicatitonContext.xml"); User user = context.getBean("user",User.class); System.out.println(user); //容器关闭,必须使用单例默认,只有容器关闭之后才能调用destroy方法 ((ClassPathXmlApplicationContext)context).close(); } }
运行结果
二月 01, 2018 8:44:32 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2a33fae0: startup date [Thu Feb 01 20:44:32 CST 2018]; root of context hierarchy 二月 01, 2018 8:44:32 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [ApplicatitonContext.xml] 初始化 二月 01, 2018 8:44:32 下午 org.springframework.context.support.AbstractApplicationContext doClose 信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@2a33fae0: startup date [Thu Feb 01 20:44:32 CST 2018]; root of context hierarchy User [id=1, name=zs] 销毁
生命周期管理
两个时机
Spring可以管理实例化bean之间以及销毁之前的行为
注入依赖关系之后:
- 使用init-method属性:通过指定init-method属性,确定某个方法应该在Bean依赖关系结束之后执行。这种方式无需要将代码与Spring的接口耦合在一起代码污染极小。通常在bean当中进行方法定义如init()方法,然后在配置文件Bean元素中加入init-method属性来实现这个过程。
- 实现InnitializingBean接口:这种方式无须指明init-method属性,当窗口依赖注入以后,会自动调用afterPropertiesSet方法,它和init-method执行效果一样,但这种方式属于侵入性的代码设计不推荐使用
销毁Bean之前:
- destroy-method:用于在执行Bean销毁之前所执行的方法,这种方式和init-method一样无压需要代码与Spring的接口耦合在一起代码污染极小。在bean中加入destory-method属性和实现这个过程
- 实现DisposeableBean接口:无需要指明destory-method属性,当容器依赖注入以后,会自动调用destroty方法,属于侵入性代码设计不推荐使用