Spring Bean的作用域以及lookup-method标签的使用
2017-10-17 20:42
585 查看
Spring Framework支持五种作用域,如下图所示:
singleton:表示一个容器中只会存在一个bean实例,无论在多少个其他bean里面依赖singleton bean,整个容器都只会存在一个实例。相当于是容器的全局变量。
prototype:一个容器中可能会存在多个bean实例,prototype bean的实例产生有两种情况,一种是其他bean请求依赖prototype 容器会为其他bean分别创建一个实例。另外一种就是通过ApplicationContextAware 接口的 getBean方法获取 bean的时候 容器也会创建一个新的实例。
request:这个不用多说,即容器会为每一个HTTP请求都会创建一个实例。
session:容器会为每个session创建一个bean实例
那么问题来了,由于bean的作用域不同,其实例创建的时间也不会相同,如果程序中存在一个 singleton bean 依赖了一个 request bean ,直接通过 @Autowired注解项目在启动的时候会报错的,如何解决这个问题呢?Spring 提供了lookup-method方法来解决这个问题。下面来看一个例子:
1 首先新建一个User类
5 在springContext.xml文件中配置
通过5 的配置 4中的抽象方法 createUser将返回2中bean定义的一个新的实例。
每次通过1 的请求时容器都会创建一个name=“”zsq“”的新实例。
当然spring提供了一种更加简单的方式来处理作用域不一样时属性注入的问题。
即使用@Scope标签的proxyMode属性。比如我要将一个Student注册为作用域为session的bean,并在单实例的loginController中注入。
1 首先建立一个
如果要在xml文件中实现这一步可以在springContext.xml文件中注入
<bean id="student" calss="com.zsq.cn.login.entity.Student" scope="session">
<property name="name">zsq</property>
<property name="age">22</property>
//下面两个二选一
<aop:scoped-proxy />//如果Student是一个类,并没有实现任何接口这样配置将采用CGLIB代
<aop:scoped-proxy proxy-target-class="false" />//如果Student实现了一个接口,这样配置将采用JDK动态代理
</bean>
2 在loginController中注入student
@Autowired
private Student student;
@RequestMapping("/")
public String home(Model model){
model.addAttribute("user", new User());
student.setAge(22);
return "home/index";
}
singleton:表示一个容器中只会存在一个bean实例,无论在多少个其他bean里面依赖singleton bean,整个容器都只会存在一个实例。相当于是容器的全局变量。
prototype:一个容器中可能会存在多个bean实例,prototype bean的实例产生有两种情况,一种是其他bean请求依赖prototype 容器会为其他bean分别创建一个实例。另外一种就是通过ApplicationContextAware 接口的 getBean方法获取 bean的时候 容器也会创建一个新的实例。
request:这个不用多说,即容器会为每一个HTTP请求都会创建一个实例。
session:容器会为每个session创建一个bean实例
那么问题来了,由于bean的作用域不同,其实例创建的时间也不会相同,如果程序中存在一个 singleton bean 依赖了一个 request bean ,直接通过 @Autowired注解项目在启动的时候会报错的,如何解决这个问题呢?Spring 提供了lookup-method方法来解决这个问题。下面来看一个例子:
1 首先新建一个User类
public class User { private String name; private String password; private int age; //省略setter 和 getter }2 将这个User类注册成为 request 作用域的bean 在springContext.xml文件中
<bean id="user" class="com.zsq.cn.login.entity.User" scope="request"> <property name="name" value="zsq" /> </bean>3 新建一个controller
@Controller public class LoginController extends BaseException{ @Autowired private LookupMethodService lookupMethodService; @RequestMapping("/") public String home(Model model){ User user = lookupMethodService.getUser(); System.out.println(user.toString()); return "home/index"; } }4 新建一个service 以及其实现类
public interface LookupMethodService { User getUser(); } @Service public abstract class LookupMethodServiceImpl implements LookupMethodService { @Override public User getUser() { return creatUser(); } public abstract User creatUser(); }
5 在springContext.xml文件中配置
<bean id="lookupMethodServiceImpl" class="com.zsq.cn.login.service.impl.LookupMethodServiceImpl"> <lookup-method name="creatUser" bean="user" /> </bean>
通过5 的配置 4中的抽象方法 createUser将返回2中bean定义的一个新的实例。
每次通过1 的请求时容器都会创建一个name=“”zsq“”的新实例。
当然spring提供了一种更加简单的方式来处理作用域不一样时属性注入的问题。
即使用@Scope标签的proxyMode属性。比如我要将一个Student注册为作用域为session的bean,并在单实例的loginController中注入。
1 首先建立一个
@Component @Scope(value="session",proxyMode=ScopedProxyMode.TARGET_CLASS) //如果Student是一个类,并没有实现任何接口,那么将proxyMode设置为ScopedProxyMode.TARGET_CLASS,将采用CGLIB代理, //如果Student实现了一个接口,那么可以将proxyMode设置为ScopedProxyMode.INTERFACES,将采用JDK的动态代理, public class Student { private String name; private int age; //省略setter、getter }
如果要在xml文件中实现这一步可以在springContext.xml文件中注入
<bean id="student" calss="com.zsq.cn.login.entity.Student" scope="session">
<property name="name">zsq</property>
<property name="age">22</property>
//下面两个二选一
<aop:scoped-proxy />//如果Student是一个类,并没有实现任何接口这样配置将采用CGLIB代
<aop:scoped-proxy proxy-target-class="false" />//如果Student实现了一个接口,这样配置将采用JDK动态代理
</bean>
2 在loginController中注入student
@Autowired
private Student student;
@RequestMapping("/")
public String home(Model model){
model.addAttribute("user", new User());
student.setAge(22);
return "home/index";
}
相关文章推荐
- Spring Bean的作用域以及lookup-method标签的使用
- Spring Bean的作用域以及lookup-method标签的使用
- Spring Bean的作用域以及lookup-method标签的使用
- Spring学习笔记 关于Bean定义的重用-使用abstract以及parent标签属性
- Spring学习笔记 关于Bean定义的重用-使用abstract以及parent标签属性
- spring中bean的作用域与懒加载及初始化方法和销毁方法以及spring容器的正常关闭
- Spring - lookup-method使用示例
- spring bean标签,及其子标签使用
- spring配置文件中bean标签中init-method和destroy-method和用注解方式配置
- Bean作用域的配置以及 Spring各种注入方式实例 list set map props
- Spring学习之使用标签来标记资源(@Component、@Repository、 @Service和@Controller)以及使用方式(包含如何在jsp中使用)
- spring的Bean注入和P标签使用
- Spring - lookup-method使用示例
- Spring的XML配置文件中的bean的子元素lookup-method的作用是什么
- 【SSH三大框架】Spring基础第一篇:搭建Spring环境、实例化Bean、管理Bean的作用域以及Bean的生命周期
- 3.4 spring- lookup-method 子元素的使用与解析
- Spring学习笔记 关于Bean属性的初始化 - 使用inner bean以及List, Map与Set的初始化
- Spring中使用标签定义bean
- Spring中使用Quartz的2种方法(extends QuartzJobBean与使用MethodInvokingJobDetailFactoryBean)
- (2)Spring的三种实例 bean 的方式 以及 Spring中bean的作用域。 以及 bean的生命周期