Spring中Bean的创建方式
创建bean的三种方式:
- 默认构造函数
- 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入Spring容器)
- 使用工厂中的静态方法
这三种方式中第一种适用于我们自己写的代码,因为只有我们自己写的代码我们才可以加上构造函数,如果是第三方的我们无法加上构造函数。第二种和第三种方式就是为了解决想要获取第三方的对象而存在的,此时我们只需要找到获取那个对象的工厂方法就可以获取对象了。
构造函数
在spring的配置文件中使用bean标签,配以id和class属性之后且没有其它的属性和标签时,采用的就是默认构造函数创建bean对象,此时如果对象没有构造方法创建会失败。
AccountServiceImpl 类
public class AccountServiceImpl implements AccountService {
public AccountServiceImpl() {
System.out.println("构造方法调用");
}
@Override
public int addMoney(int money) {
System.out.println("向账户中加钱:" + money);
return 0;
}
@Override
public void saveAccount(Account account) {
System.out.println("saveAccount方法执行了");
}
}
bean.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="accountService" class="com.sks.service.imp.AccountServiceImpl"></bean>
</beans>
测试
/**
* 使用构造函数创建bean对象
*/
@Test
public void test4() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:bean.xml");
AccountService accountService = (AccountService)applicationContext.getBean("accountService");
System.out.println("accountService:" + accountService);
}
可以看到在控制打印了以下内容
如果注释掉默认构造函数再执行测试代码,则会出错。
使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入Spring容器)
这个InstanceFactory 类模拟的是第3方jar包中的类。
InstanceFactory 类
public class InstanceFactory {
public AccountService getAccountService() {
System.out.println("getAccountService方法执行了");
return new AccountServiceImpl();
}
}
bean.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!---->
<bean id="instanceFactory" class="com.sks.util.InstanceFactory"></bean>
<!--factory-->
<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
</beans>
测试
/**
* 使用其它类中的方法创建对象
*/
@Test
public void test5() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:bean.xml");
AccountService accountService = (AccountService) applicationContext.getBean("accountService");
System.out.println("accountService:" + accountService);
}
在控制台输出了以下内容:
这说明了我们是通过InstanceFactory去获取到AccountService对象的。
使用工厂中的静态方法创建对象
staticFactory 类
public class staticFactory {
public static AccountService getAccountService() {
System.out.println("静态工厂方法执行了");
return new AccountServiceImpl();
}
}
bean.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="accountService" class="com.sks.util.staticFactory" factory-method="getAccountService"></bean>
</beans>
测试
/**
* 使用静态工厂中的方法创建对象
*/
@Test
public void test6() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:bean.xml");
AccountService accountService = (AccountService) applicationContext.getBean("accountService");
System.out.println("accountService:" + accountService);
}
可以看到在控制台打印了以下内容:
Spring中Bean的作用范围
Spring中Bean的作用范围:
- singleton:单例,默认是单例;
- prototype:多例;
- request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效;
- session:对于每次HTTP Session,使用session定义的Bean对象产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效;
- global session:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效,此作用域一般用于集群环境下。
在Spring中通过bean标签的scope属性去配置作用域:
Spring中Bean的生命周期
单例对象的生命周期:容器启动,单例对象创建,容器关闭,单例对象被销毁。
多例对象的生命周期:当我们使用对象时,Spring框架为我们创建对象,对象只要是在使用中就会一直存活,当我们长时间不用且没有别的对象引用的时候,由垃圾回收线程回收。