<bean id="role" class="spring.chapter2.maryGame.Role" scope="singleton"/>
- 这里的scope就是用来配置spring bean的作用域,它标识bean的作用域。在spring2.0之前bean只有2种作用域即:singleton(单例)、non-singleton(也称prototype),Spring2.0以后,增加了session、request、global session三种专用于Web应用程序上下文的Bean。因此,默认情况下Spring2.0现在有五种类型的Bean。当然,Spring2.0对Bean的类型的设计进行了重构,并设计出灵活的Bean类型支持,理论上可以有无数多种类型的Bean,用户可以根据自己的需要,增加新的Bean类型,满足实际应用需求。
- 1、singleton作用域
- 当一个bean的作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把一个bean定义设置为singleton作用域时,Spring IOC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例,这里要注意的是singleton作用域和GOF设计模式中的单例是完全不同的,单例设计模式表示一个ClassLoader中只有一个class存在,而这里的singleton则表示一个容器对应一个bean,也就是说当一个bean被标识为singleton时候,spring的IOC容器中只会存在一个该bean。
- 配置实例:
- <bean id="role" class="spring.chapter2.maryGame.Role" scope="singleton"/>
- 或者
- <bean id="role" class="spring.chapter2.maryGame.Role" singleton="true"/>
- 2、prototype
- prototype作用域部署的bean,每一次请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)都会产生一个新的bean实例,相当与一个new的操作,对于prototype作用域的bean,有一点非常重要,那就是Spring不能对一个prototype bean的整个生命周期负责,容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法,而对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。(让Spring容器释放被singleton作用域bean占用资源的一种可行方式是,通过使用bean的后置处理器,post-processor,该处理器持有要被清除的bean的引用。)
- 配置实例:
- <bean id="role" class="spring.chapter2.maryGame.Role" scope="prototype"/>
- 或者
- <beanid="role" class="spring.chapter2.maryGame.Role" singleton="false"/>
<bean id="meetAction" class="com.web.actions.MeetsAction"
scope="prototype">
<property name="meetsService" ref="meetsService" />
</bean>
singleton模式指的是对某个对象的完全共享,包括代码空间和数据空间,说白了,如果一个类是singleton的,假如这个类有成员变量,那么这个成员变量的值是各个线程共享的(有点类似于static的样子了),当线程A往给变量赋了一个值以后,线程B就能读出这个值。因此,对于前台Action,肯定不能使用singleton的模式,必须是一个线程请求对应一个独立的实例。推而广之,只要是带数据成员变量的类,为了防止多个线程混用数据,就不能使用singleton。对于我们用到的Service、Dao,之所以用了singleton,就是因为他们没有用到数据成员变量,如果谁的Service需要数据成员变量,请设置singleton=false。 有状态的bean都使用Prototype作用域,而对无状态的bean则应该使用singleton作用域。在 Spring2.0中除了以前的Singleton和Prototype外又加入了三个新的web作用域,分别为request、session和 global session。如果你希望容器里的某个bean拥有其中某种新的web作用域,除了在bean级上配置相应的scope属性,还必须在容器级做一个额外的初始化配置。即在web应用的web.xml中增加这么一个ContextListener: org.springframework.web.context.request.RequestContextListener 以上是针对Servlet 2.4以后的版本。比如Request作用域。
<bean id="personAction" scope="prototype" class="quickstart.action.PersonAction"> <constructor-arg ref="personService" /> </bean>
在配置文件中,bean默认是单例模式,应用服务器启动后就会立即创建bean,以后就可以重复使用。
这带来一个问题,bean的全局变量被赋值以后,在下一次使用时会把值带过去。也就是说,bean是有状态的。
在web状态下,请求是多线程的,全局变量可能会被不同的线程修改,尤其在并发时会带来意想不到的bug。
而在开发时,访问量很小,不存在并发、多线程的问题,程序员极有可能会忽视这个问题。
所以在配置action bean时,应使用scope="prototype",为每一次request创建一个新的action实例。这
符合struts2的要求,struts2为每一个request创建一个新的action实例。当request结束,bean就会被jvm
销毁,作为垃圾收回。
当然,也可以设置scope="session",也能避免web中action的并发问题,只为当前用户创建一次bean,直至 session消失。在这种情况下,对当前用户而言,bean是有状态的。好处就是少创建bean的实例,有那么一 点点性能的提升
应用场景: 1. 多数情况下应使用prototype 2. 若用户不多,且频繁操作(频繁使用action),硬件一般,可以考虑session,兴许还能提升一点点性能。
最近突然想到一个问题
以前在用struts2(注解)+spring
struts的action拖给spring管了(spring的bean在Ioc容器范围内默认都是singlen的),但是没有加@scope("prototype")却从来没有出现过线程安全问题。
而一年前还在学校时做ssh2(没用注解)练习时,不在bean后加prototype都会出现线程安全问题,当时所有的action后都加了scope=prototype。
难道注解和不用注解,struts2创建action的方式不一样?
于是做了个测试
- public class TestAction extends BaseAction {
- @Autowired
- private UserService userService;
- @Action("test")
- public String test() throws Exception {
- System.out.println("action HashCode:"+this.hashCode());
- userService.getUserName();
- return "success";
- }
- }
- @Service
- public class UserService {
- public void getUserName(){
- System.out.println("service HashCode:"+hashCode()); }
- }
连续运行3次发现输出:
- action HashCode:9928297
- service HashCode:32262619
- action HashCode:13620718
- service HashCode:32262619
- action HashCode:19792917
- service HashCode:32262619
输出结果说明 每次的action是不一样的
而每次的service是同一个也就是单例的
(难道action并没有交个spring托管)
又把以前在学校做的老项目(纯xml)拿来 把以前的scope="prototype"去掉
发现action确实是单例的 再加上scope="prototype"后action不是单例了
所以struts2(注解) 在和spring集成时action默认是new的,不用注解spring扫描action的话也是用的new。
而非注解时如果把action加入bean的话默认是单例的。
所以如果大家struts2是用注解的话就不需要在action上加@scope("prototype")了;
当指定struts.objectFactory为spring时,struts2框架就会把bean转发给spring来创建,装配,注入。但是bean创建完成之后,还是由struts容器来管理其生命周期。配置方式:
(1)struts.xml中:
- <</span>constant name="struts.objectFactory" value="spring" />
(2)struts.properties中:
- struts.objectFactory=spring
通常情况下,这样子就够了,然后在struts的action-mapping配置文件中,如下:
- <action name="user" class="com.myapp.admin.web.action.user.UserAction"></action>
即可,如果在Action中有依赖于其它的BEAN,也会被自动注入进来。这时候,Action实例是以prototype方式创建的,SPRING会为每个请求创建一个ACTION的实例。
在某些时候,你可能希望不仅仅让SPRING创建和装配Action对象,还希望让SPRING完全管理这些对象,如希望使用AOP或者希望使用acegi时。这时候,只需要在spring的配置文件中定义这些action 即可。如在applicationContext.xml文件中:
- <bean id="user" class="com.myapp.web.action.user.UserAction"/>
然后在action-mapping中,指定class="user"即可。
Struts和Spring整合方案有两种:
方案一:
使用委托方式,将struts中的Action配置到spring中,然后通过委托方式来调用Action
相关推荐
* * * * Bean的作用域 作用域的种类 Spring 4.3中为Bean的实例定义了7种作用域,如下表所示: 注意:在上表7种作用域中,singleton和prototype是最常用的两种作用域。 在Spring配置文件中,可以使用元素的scope属性...
Spring IOC Bean标签属性介绍 0.Bean标签属性介绍 1.0 新建一个Maven工程 1.1 pom.xml 1.2 实体类JavaBean 1.2.1 User类 1.3 当Scope="singleton"时 1.4 当 Scope="singleton" 且 lazy-init="true" 时 1.5 当scope=...
创建对象的模式(使用范围):scope控制,可以使用singleton和prototype d.初始化: e.资源释放:仅对单例对象有效 (2)IoC概念 Inversion of Control 控制反转或控制转移 Don't Call Me,We will call you! ...
我的博客中“maven环境搭建及Spring入门”的项目代码。在idea中运行成功。 1。创建IOC容器 2。通过xml装配对象 【简单类型用value、复杂(引用类型)用ref、数组,集合,Map的装配】 3。IOC容器获取bean的方式 * ...
创建对象的模式(使用范围):scope控制,可以使用singleton和prototype d.初始化: e.资源释放:仅对单例对象有效 (2)IoC概念 Inversion of Control 控制反转或控制转移 Don't Call Me,We will call you! ...
创建对象的模式(使用范围):scope控制,可以使用singleton和prototype d.初始化: e.资源释放:仅对单例对象有效 (2)IoC概念 Inversion of Control 控制反转或控制转移 Don't Call Me,We will call you! ...
(2)、@Bean注解默认作用域为单例singleton作用域,可通过@Scope(“prototype”)设置为原型作用域; (3)、既然@Bean的作用是注册bean对象,那么完全可以使用@Component、@Controller、@Service、@Ripository等注解...
prototype:,设定创建出的对象保存在spring容器中,是一个非单例的对象 非单例的对象是在调用getBean()方法时才创建对象,在同一个bean获取的资源时,用getBean()方法得到的对象都不相同 request、session、...
Spring容器IOC和di的整个启动过程: 38 3.8 spring中的继承 38 拓展spring为类中的属性赋值: 40 小结: 47 面向接口编程: 47 4 面向切面编程 52 4.1 代理模式 52 代理模式拓展: 52 4.1.1 JDK动态代理 58 JDK动态...
-VS--namebeans.xml简单属性的注入UserDAOImpl连接池需要bean的scope属性singleton单例prototype原型官方文档,scope集合注入设置好set,get方法在bean中设置好值自动装配auto-wire生命周期lazy-initinit-method,...
@Scope("prototype") @Scope("singleton") 可以使用@Scope注解,标记这个类是单例还是多例,默认是单例。 二、使用单例引起线程安全问题的例子 那究竟什么时候会用到呢?我相信大多数人写的代码都不会去考虑这个...
JSP 中Spring Bean 的作用域详解 Bean元素有一个scope属性,用于定义Bean的作用域,该属性有如下五个值: 1>singleton: 单例模式,在整个spring IOC容器中,单例模式作用域的Bean都将只生成一个实例。一般Spring...
scope:prototype/singleton init-method destroy-method API BeanFactory:使用这个工厂创建对象的方式都是懒加载,在调用的时候再创建 ClassPathXmlApplicationContext:使用这个工厂创建对象,他会根据...
SpringEL和资源调用 注入普通字符 注入操作系统属性 注入表达式云算结果 注入其他Bean的属性 注入文件内容 注入网址内容 注入属性文件 Bean的初始化和销毁 Java配置方式 注解方式 ...
使用scope来控制bean的作用范围,SCOPE_SINGLETON创建一个bean,SCOPE_PROTOTYPE表示创建多个bean实例对象 * 2.返回值等同于配置文件中的Class,方法名等同于id(xml) * 3.懒加载在获取容器中对象的时候创建对象,...
3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................
<bean id="departmentDao" class="my.aop.dao.DepartmentDaoJdbcImpl" scope="prototype"> <property name="dataSource" ref="dataSource"></property> ...
3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................