一、Bean的实例化
- 创建一个web项目,并在该项目的lib目录下加入Spring支持和依赖的JAR包
- 在该项目的src目录下创建一个com.example.beans包,在其中创建类Bean1
- 在com.example.beans包下,创建Spring的配置文件beans1.xml(或者applicationContex.xml),在配置文件中定义一个id为bean1的Bean,并通过class属性指定其对应的实现类为Bean1
<?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="bean" class="com.example.beans.bean"/>
</beans>
在com.example.beans包中,创建测试类test1,来测试构造器是否能实例化Bean。
package com.example.beans;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
public static void main(String[] args) {
String xmlPath="com/example/beans/beans1.xml";
# xmlPath为配置文件的位置
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath);
# 加载配置文件,对Bean进行实例化
bean bean1=(bean)applicationContext.getBean("bean");
System.out.println(bean1);
}
}
- 输出结果
二、静态工厂方式实例化Bean
这要求开发者创建一个静态工厂的方法来创建Bean的实例。
其中Bean配置中的class属性所指定的不再是Bean实例的实现类,而是静态工厂类。
同时还需要使用factory-method属性来指定所创建的静态工厂方法。
下面是步骤:
- 在src下创建com.example.static_factory包,并在该包下创建一个Bean2类。
- 在com.example.static_factory包下创建一个MyBean2Factory类,并在其中创建一个静态方法creatBean()来返回Bean2。
package com.example.static_factory;
public class MyBean2Factory {
public static Bean2 createBean() {
return new Bean2();
}
}
- 在com.example.static_factory包下,创建Spring配置文件beans2.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">
<!- class属性所指定的为静态工厂类,同时使用factory-method属性来指定所创建的静态工厂方法 ->
<bean id="bean2"
class="com.example.static_factory.MyBean2Factory"
factory-method="createBean"/>
</beans>
- 在com.example.static_factory包下,创建一个测试类test,java,来测试使用静态工厂方式是否实例化Bean2
package com.example.static_factory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
public static void main(String[] args) {
String xmlPath="com/example/static_factory/beans2.xml";
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath);
Bean2 bean2=(Bean2)applicationContext.getBean("bean2");
System.out.println(bean2);
}
}
- 测试结果
三、实例工厂方式实例化Bean
这要求开发者创建一个实例工厂的方法来创建Bean的实例。
其中Bean配置中的class属性所指定的不再是Bean实例的实现类,而是实例工厂类。
同时还需要使用factory-method属性来指定所创建的实例工厂方法。
下面是步骤:
- 在src目录下,创建一个创建一个com.example.factory包,并在该包中创建Bean3类。
- 在com.example.factory包中创建工厂类MyBean3Factory,在类中使用无参构造方法输出“bean3工厂实例化中”
package com.example.factory;
// 实例工厂
public class MyBean3Factory {
public MyBean3Factory() {
System.out.println("bean3工厂实例化中");
}
public static Bean3 createBean() {
return new Bean3();
}
}
- 在com.example.factory包中,创建Spring配置文件bean3.xml。
首先配置一个工厂bean,然后配置了需要实例化的Bean。在id为bean3的Bean中,
使用factory-bean属性指向配置的实例化工厂,该属性值就是工厂Bean的id.
使用factory-method属性来确定使用使用工厂中的creatBean()方法。
<?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-4.3.xsd">
<!-- 配置工厂 -->
<bean id="myBean3Factory"
class="com.example.factory.MyBean3Factory"/>
<!-- 使用factory-bean属性指向配置实例化工厂,
使用factory-method属性确定使用工厂中的哪个方法 -->
<bean id="bean3"
factory-bean="myBean3Factory"
factory-method="createBean"/>
</beans>
- 在com.example.factory包中,创建测试类test,来测试实例工厂是否实例化Bean。
package com.example.factory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
public static void main(String[] args) {
String xmlPath="com/example/factory/beans3.xml";
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath);
Bean3 bean3=(Bean3)applicationContext.getBean("bean3");
System.out.println(bean3);
}
}
- 测试结果
四、Bean的作用域(通过scope属性来指定)
统一格式:<bean id="userInfo" class="cn.example.UserInfo" scope="作用域"/>
singleton(单例) | 当Bean的作用域为singleton的时候,Spring容器中只会存在一个共享的Bean实例,所有对Bean的请求只要id与bean的定义相匹配,则只会返回bean的同一实例。 | <bean id="userInfo" class="cn.example.UserInfo" scope="singleton"/> |
prototype(原型) | 每次通过Spring容器获取的prototype定义的Bean时,容器都将创建一个新的Bean实例 | <bean id="userInfo" class="cn.example.UserInfo" scope=" prototype "/> |
request | 在一次HTTP请求中,容器会返回该Bean的同一个实例。对于不同的HTTP请求则会产生一个新的Bean,而且改Bean仅在当前HTTP Request内失效。 | <bean id="userInfo" class="cn.example.UserInfo" scope=" request "/> |
session | 在一次HTTP Session中,容器会返回该Bean的同一个实例,对不同的HTTP请求则会产生一个新的Bean,而且该Bean仅在当前HTTP Session内有效。 | <bean id="userInfo" class="cn.example.UserInfo" scope=" session "/> |
global session | 在一全局HTTP Session中,容器会返回该Bean的同一个实例。仅在使用porlet上下文时有效。 | <bean id="userInfo" class="cn.example.UserInfo" scope=“globalSession"/> |
application | 为每个ServiceContext对象创建一个实例。仅在Web相关的ApplicationContext中生效。 | |
websocket | 为每个websocket对象创建一个实例。仅在Web相关的ApplicationContext中生效。 |
五、Bean的装配(依赖注入)方式——基于XML的装配、基于注解(annotation)的装配和自动装配等
其中最常用的时基于注解的装配。
- 基于XML的装配(Spring提供了两种XML的装配方式:设值注入和构造注入)
通常在Spring实例化Bean的过程中,Spring首先会调用Bean的默认构造方法来实例化Bean对象,然后通过反射的方式调用setter方法来注入属性值。因此,设值注入要求一个Bean必须满足一下两点要求:
1.Bean类必须提供一个默认的无参构造函数
2.Bean类必须为需要注入的属性提供对应的setter方法。
设置注入需要使用<bean>元素的子元素<property>来为每个属性注入值。
构造注入需要配置文件里使用<bean>元素的子元素<constructor-arg>来定义构造方法的参数,可以使用其value属性来设置该参数的值。
例子如下:
1.在src目录下,创建一个com.example.assemble包,并在包下创建一个User类。
package com.example.assemble;
import java.util.List;
public class User {
private String username;
private Integer password;
private List<String> list;
/**
* 使用构造注入
* 提供带所有参数的有参构造方法
*/
public User(String username, Integer password, List<String>list) {
super();
this.username=username;
this.password=password;
this.list=list;
}
/**
* 使用设值注入
* 提供默认空参构造方法
* 为所有属性提供setter方法
*/
public User() {
super();
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getPassword() {
return password;
}
public void setPassword(Integer password) {
this.password = password;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + ", list=" + list + "]";
}
}
2.在com.example.assemble包中,创建配置文件beans.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-4.3.xsd">
<!-- 使用构造注入方式装配User实例 -->
<bean id="user1" class="com.example.assemble.User">
<constructor-arg index="0" value="leopard"/>
<constructor-arg index="1" value="123456"/>
<constructor-arg index="2">
<list>
<value>"constructorValue1"</value>
<value>"constructorValue2"</value>
</list>
</constructor-arg>
</bean>
<!-- 使用设置注入方式装配User实例 -->
<bean id="user2" class="com.example.assemble.User">
<property name="username" value="张三"/>
<property name="password" value="987654321"/>
<property name="list">
<list>
<value>"constructorValue1"</value>
<value>"constructorValue2"</value>
</list>
</property>
</bean>
</beans>
3.在com.example.assemble包中,创建text.java
package com.example.assemble;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
public static void main(String[] args) {
String xmlPath="com/example/assemble/beans.xml";
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath);
//构造方式输出结果
User user1=(User)applicationContext.getBean("user1");
System.out.println(user1.toString());
//设值方式输出结果
User user2=(User)applicationContext.getBean("user2");
System.out.println(user2.toString());
}
}
测试结果:
- 基于注解(Annotation)的装配
@Component | 可以使用它来注解描述Bean,仅仅表示一个组件Bean,并且可以作用在任何层次。 使用时只需要将该注解标注在相应的类上。 |
---|---|
@Repositiry | 用于将数据访问层(DAO层)的类标识为Bean,其功能与@Component相同。 |
@Service | 通常作用在业务层(Service层),用于将业务层的类标识为Bean。其功能与@Component相同。 |
@Controller | 通常作用在控制层(如Spring MVC的Controller) ,用于将控制层的类标识为Bean。其功能与@Component相同。 |
@Autowired | 用于对Bean的属性变量、属性的setter方法及构造方法进行标注,配合对应注解处理器完成Bean的自动配置工作。默认按照Bean类型进行装配。 |
@Resource | 其作用与@Autowired一样,区别在于@Autowired默认按照Bean类型装配,而@Resource默认按照Bean实例名称进行装配。@Resource中有两个重要属性:name和type。 Spring将name属性解析为Bean实例名称,type属性解析为Bean实例类型 |
@Qualifier | 与@Autowired注解配合使用,会将默认的按Bean类型装配修饰改为按Bean的实例名称装配,Bean的实例名称由@Qualifier注解的参数指定。 |
- 自动装配