- 浏览: 971459 次
- 性别:
- 来自: 江西上饶
-
文章分类
- 全部博客 (460)
- p.spring (56)
- p.maven (20)
- p.ant (17)
- p.jee (18)
- p.jse (33)
- p.ofbiz (31)
- p.软件工程 (8)
- p.struts2 (5)
- p.hibernate (5)
- linux (25)
- 设计模式 (2)
- p.javascript (11)
- 硬件 (1)
- p.jsp (2)
- p.windows批处理 (1)
- 操作系统问题 (5)
- 算法 (1)
- p.mysql (7)
- p.sql (5)
- p.c (1)
- google产品 (0)
- 内存 (1)
- p.struts (1)
- p.freemarker (7)
- p.css (4)
- p.log4j (10)
- p.html (3)
- 淘宝产品 (0)
- 其他 (3)
- 编译器 (0)
- svn (4)
- p.spring.security (11)
- 图形 (0)
- p.xml (1)
- p.ssh (0)
- p.jquery (4)
- p.jdbc (3)
- p.flex (0)
- p.c++ (0)
- p.c#Net (0)
- p.assembly (0)
- p.sqlserver (0)
- p.其他 (3)
- p.webwork (21)
- p.wap (12)
- p.cglib (1)
- p.jee服务器 (11)
- windows (2)
- p.iphone (1)
- p.java.分布式与集群 (2)
- p.ibatis (16)
- p.eclipse (5)
- 架构 (2)
- http协议 (5)
- 我的个人标准 (2)
- 多线程 (1)
- 奇怪问题 (5)
- p.jira (13)
- p.httpclient (1)
- 服务器.apache (11)
- 安全防范 (1)
- p.PODAM (1)
- p.junit (16)
- fop (2)
- 硬盘安装 (1)
- powerdesigner (0)
- 单元测试 (1)
- apache commons (4)
- tomcat+apache集群 (10)
- 各类诡辩 (1)
- 安卓 (8)
- qvod (1)
- java编程基础知识考试考点及答案 (0)
- 工作总结 (4)
- oracle (0)
- spring的util工具 (3)
- json (2)
- maven (3)
- jms (19)
- p.bat (3)
- hadoop (2)
- git (3)
- nginx (1)
- p.移动开发 (1)
- shiro (3)
- 游戏破解 (1)
- react-native (7)
- ios开发 (1)
- webmagic (6)
- socks5 (1)
最新评论
-
weituotian:
说的不好,没人看的
公司系统中的菜单功能和权限功能 -
石不易:
非常详细的注解~
绑定端口和IP,Listen 与VirtualHost指令 -
spring_springmvc:
spring mvc demo教程源代码下载,地址:http: ...
spring mvc -
liyixing1:
PandaDONG 写道谢谢你啊,我已经下下来了,只是还有很多 ...
jira war安装 -
liyixing1:
PandaDONG 写道谢谢你啊,我已经下下来了,只是还有很多 ...
jira war安装
如
在大部分情况下,容器中的bean都是singleton类型的。如果一个singleton bean要引用另外一个singleton bean,或者一个非singleton bean要引用另外一个非singleton bean时,通常情况下将一个bean定义为另一个bean的property值就可以了。不过对于具有不同生命周期的bean来说这样做就会有问题了,比如在调用一个singleton类型bean A的某个方法时,需要引用另一个非singleton(prototype)类型的bean B,对于bean A来说,容器只会创建一次,这样就没法在需要的时候每次让容器为bean A提供一个新的的bean B实例。
上述问题的一个解决办法就是放弃控制反转。通过实现BeanFactoryAware接口让bean A能够感知bean 容器,并且在需要的时候通过使用getBean("B")方式
向容器请求一个新的bean B实例
// a class that uses a stateful Command-style class to perform some processing
package fiona.apple;
// lots of Spring-API imports
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
public class CommandManager implements BeanFactoryAware {
private BeanFactory beanFactory;
public Object process(Map commandState) {
// grab a new instance of the appropriate Command
Command command = createCommand();
// set the state on the (hopefully brand new) Command instance
command.setState(commandState);
return command.execute();
}
// the Command returned here could be an implementation that executes asynchronously, or whatever
protected Command createCommand() {
return (Command) this.beanFactory.getBean("command"); // notice the Spring API dependency
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}
上面的例子显然不是最好的,因为业务代码和Spring Framework产生了耦合。方法注入,作为Spring IoC容器的一种高级特性,可以以一种干净的方法来处理这种情况。
Lookup方法注入
这究竟是不是方法注入……
有点像Tapestry 4.0的页面,写上abstract属性,Tapestry会在运行时用具体实现将其覆盖。
Lookup方法注入利用了容器的覆盖受容器管理的bean方法的能力,从而返回指定名字的bean实例。在上述场景中,Lookup方法注入适用于原型bean。Lookup方法注入的内部机制是Spring利用了CGLIB库在运行时生成二进制代码功能,通过动态创建Lookup方法bean的子类而达到复写Lookup方法的目的。
如果你看下上个代码段中的代码(CommandManager类),Spring容器动态覆盖了createCommand()方法的实现。你的CommandManager类不会有一点对Spring的依赖,在下面这个例子中也是一样的:
package fiona.apple;
// no more Spring imports!
public abstract class CommandManager {
public Object process(Object commandState) {
// grab a new instance of the appropriate Command interface
Command command = createCommand();
// set the state on the (hopefully brand new) Command instance
command.setState(commandState);
return command.execute();
}
// okay... but where is the implementation of this method?
protected abstract Command createCommand();
}
在包含被注入方法的客户类中(此处是CommandManager),此方法的定义必须按以下形式进行:
<public|protected> [abstract] <return-type> theMethodName(no-arguments);
如果方法是抽象的,动态生成的子类会实现该方法。否则,动态生成的子类会覆盖类里的具体方法。让我们来看个例子:
<!-- a stateful bean deployed as a prototype (non-singleton) -->
<bean id="command" class="fiona.apple.AsyncCommand" scope="prototype">
<!-- inject dependencies here as required -->
</bean>
<!-- commandProcessor uses statefulCommandHelper -->
<bean id="commandManager" class="fiona.apple.CommandManager">
<lookup-method name="createCommand" bean="command"/>
</bean>
在上面的例子中,标识为commandManager的bean在需要一个新的command bean实例时,会调用createCommand方法。重要的一点是,必须将command部署为prototype。当然也可以指定为singleton,如果是这样的话,那么每次将返回相同的command bean实例!
我做了个例子
目录结构
需要asm.jar和cglib.jar,cglib的版本会依赖对应的版本号,如果发现了asm和cglib的错误,可以换版本试试
package com.liyixing.spring.service;
public interface IAccountService {
public void getAccount();
}
package com.liyixing.spring.service;
public interface IDownloadService {
public void getDownload();
}
package com.liyixing.spring.service.imp;
import com.liyixing.spring.service.IDownloadService;
public class DownloadService implements IDownloadService {
public void getDownload() {
System.out.println("getDownload()");
}
}
package com.liyixing.spring.service.imp;
import com.liyixing.spring.service.IAccountService;
import com.liyixing.spring.service.IDownloadService;
public abstract class AccountService implements IAccountService {
private IDownloadService downloadService;
public IDownloadService getDownloadService() {
return downloadService;
}
public void setDownloadService(IDownloadService downloadService) {
this.downloadService = downloadService;
}
public void getAccount() {
downloadService = look();
downloadService.getDownload();
System.out.println("getAccount()");
System.out.println("down is " + downloadService);
System.out.println();
}
public abstract IDownloadService look();
}
这个类是抽象类,它的look方法也是抽象方法;
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-2.5.xsd">
<bean id="accountService" class="com.liyixing.spring.service.imp.AccountService">
<lookup-method name="look" bean="downloadService"/>
</bean>
<bean id="downloadService" class="com.liyixing.spring.service.imp.DownloadService"
scope="prototype">
</bean>
</beans>
<lookup-method name="look" bean="downloadService"/>这里设置了方法,并设置的bean属性这个属性表示将会以在look方法,返回downloadService这个类,类似的在look的动态生成的代码会有
beanFactory.getBean("downloadService");方法存在。
请注意,为了让这个动态子类得以正常工作,需要把CGLIB的jar文件放在classpath里。另外,Spring容器要子类化的类不能是final的,要覆盖的方法也不能是final的。同样的,要测试一个包含抽象方法的类也稍微有些不同,你需要自己编写它的子类提供该抽象方法的桩实现。最后,作为方法注入目标的bean不能是序列化的(serialized)。
现ServiceLocatorFactoryBean(在org.springframework.beans.factory.config包里)的用法和ObjectFactoryCreatingFactoryBean的有些相似,不同的是它允许你指定自己的lookup接口,不一定非要用Spring的lookup接口,比如ObjectFactory。要详细了解这种方法请参考ServiceLocatorFactoryBean的Javadocs(它的确减少了对Spring的耦合)。
能够在HTTP request或者Session(甚至自定义)作用域中定义bean固然很好,但是Spring IoC容器除了管理对象(bean)的实例化,同时还负责协作者(或者叫依赖)的实例化。如果你打算将一个Http request范围的bean注入到另一个bean中,那么需要注入一个AOP代理来替代被注入的作用域bean。也就是说,你需要注入一个代理对象,该对象具有与被代理对象一样的公共接口,而容器则可以足够智能的从相关作用域中(比如一个HTTP request)获取到真实的目标对象,并把方法调用委派给实际的对象。
<aop:scoped-proxy/> 不能和作用域为singleton或prototype的bean一起使用。为singleton bean创建一个scoped proxy将抛出BeanCreationException异常。
让我们看一下将相关作用域bean作为依赖的配置,配置并不复杂(只有一行),但是对理解“为何这么做”以及“如何做”是很重要的。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<!-- a HTTP Session-scoped bean exposed as a proxy -->
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<!-- this next element effects the proxying of the surrounding bean -->
<aop:scoped-proxy/>
</bean>
<!-- a singleton-scoped bean injected with a proxy to the above bean -->
<bean id="userService" class="com.foo.SimpleUserService">
<!-- a reference to the proxied
'userPreferences' bean -->
<property name="userPreferences" ref="userPreferences"/>
</bean>
</beans>
要创建这样的代理,只需要在Bean作用域定义中增加一个<aop:scoped-proxy/>子元素(为了让容器可以有效的使用基于类(而不是接口)的代理,你需要在classpath中加入CGLIB包, 并且要使用Appendix A, XML Schema-based configuration配置方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
这引入的xsi的aopxsd文件
)。为什么在request,session, globalSession 和 '自定义作用域' 需要<aop:scoped-proxy/>元素?在下面配置片段中可以找到解释(注意下面 'userPreferences' Bean定义是不完整的):
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
从上述配置中可以很明显的看到singleton bean userManager被注入了一个指向HTTP Session作用域bean userPreferences的引用。singleton userManager bean会被容器仅实例化一次,并且其依赖(即userPreferences bean)也仅被注入一次。这意味着,userManager在理论上只会操作同一个userPreferences对象,即原先被注入的那个bean。而注入一个HTTP Session作用域的bean作为依赖,有违我们的初衷。因为我们想要的只是一个userManager对象,在它进入一个HTTP Session生命周期时,我们希望去使用一个HTTP Session的userPreferences对象。
当注入某种类型对象时,该对象实现了和UserPreferences类一样的公共接口(即UserPreferences实例)。并且不论我们底层选择了何种作用域机制(HTTP request、Session等等),容器都会足够智能的获取到真正的 UserPreferences对象,因此我们需要将该对象的代理注入到userManager bean中, 而userManager bean并不会意识到它所持有的是一个指向UserPreferences引用的代理。在本例中,当UserManager实例调用了一个使用UserPreferences对象的方法时,实际调用的是代理对象的方法。随后代理对象会从HTTP Session获取真正的UserPreferences对象,并将方法调用委派给获取到的实际的UserPreferences对象。
这就是当把request-, session-, 和 globalSession-scoped beans 注入到协作对象中时,需要以下的正确而完整的配置:
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
选择创建代理的类型
默认情况下,当一个bean有<aop:scoped-proxy/>标记时,Spring容器将为它创建一个基于CGLIB的类代理,这意味着你需要 将CGLIB库添加到应用的classpath中。
注意:CGLIB代理仅仅拦截public方法的调用!对于非public的方法调用,不会对目标对象产生委托。
你可以将<aop:scoped-proxy/>的属性'proxy-target-class'设置为'false'来选择标准JDK推荐的基于接口的代理,这样就不需要在应用的classpath中增加额外的库。但是,这就意味着类必须实现至少一个接口。并且所有的协作者必须通过某一个 接口来引用bean。
在大部分情况下,容器中的bean都是singleton类型的。如果一个singleton bean要引用另外一个singleton bean,或者一个非singleton bean要引用另外一个非singleton bean时,通常情况下将一个bean定义为另一个bean的property值就可以了。不过对于具有不同生命周期的bean来说这样做就会有问题了,比如在调用一个singleton类型bean A的某个方法时,需要引用另一个非singleton(prototype)类型的bean B,对于bean A来说,容器只会创建一次,这样就没法在需要的时候每次让容器为bean A提供一个新的的bean B实例。
上述问题的一个解决办法就是放弃控制反转。通过实现BeanFactoryAware接口让bean A能够感知bean 容器,并且在需要的时候通过使用getBean("B")方式
向容器请求一个新的bean B实例
// a class that uses a stateful Command-style class to perform some processing
package fiona.apple;
// lots of Spring-API imports
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
public class CommandManager implements BeanFactoryAware {
private BeanFactory beanFactory;
public Object process(Map commandState) {
// grab a new instance of the appropriate Command
Command command = createCommand();
// set the state on the (hopefully brand new) Command instance
command.setState(commandState);
return command.execute();
}
// the Command returned here could be an implementation that executes asynchronously, or whatever
protected Command createCommand() {
return (Command) this.beanFactory.getBean("command"); // notice the Spring API dependency
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}
上面的例子显然不是最好的,因为业务代码和Spring Framework产生了耦合。方法注入,作为Spring IoC容器的一种高级特性,可以以一种干净的方法来处理这种情况。
Lookup方法注入
这究竟是不是方法注入……
有点像Tapestry 4.0的页面,写上abstract属性,Tapestry会在运行时用具体实现将其覆盖。
Lookup方法注入利用了容器的覆盖受容器管理的bean方法的能力,从而返回指定名字的bean实例。在上述场景中,Lookup方法注入适用于原型bean。Lookup方法注入的内部机制是Spring利用了CGLIB库在运行时生成二进制代码功能,通过动态创建Lookup方法bean的子类而达到复写Lookup方法的目的。
如果你看下上个代码段中的代码(CommandManager类),Spring容器动态覆盖了createCommand()方法的实现。你的CommandManager类不会有一点对Spring的依赖,在下面这个例子中也是一样的:
package fiona.apple;
// no more Spring imports!
public abstract class CommandManager {
public Object process(Object commandState) {
// grab a new instance of the appropriate Command interface
Command command = createCommand();
// set the state on the (hopefully brand new) Command instance
command.setState(commandState);
return command.execute();
}
// okay... but where is the implementation of this method?
protected abstract Command createCommand();
}
在包含被注入方法的客户类中(此处是CommandManager),此方法的定义必须按以下形式进行:
<public|protected> [abstract] <return-type> theMethodName(no-arguments);
如果方法是抽象的,动态生成的子类会实现该方法。否则,动态生成的子类会覆盖类里的具体方法。让我们来看个例子:
<!-- a stateful bean deployed as a prototype (non-singleton) -->
<bean id="command" class="fiona.apple.AsyncCommand" scope="prototype">
<!-- inject dependencies here as required -->
</bean>
<!-- commandProcessor uses statefulCommandHelper -->
<bean id="commandManager" class="fiona.apple.CommandManager">
<lookup-method name="createCommand" bean="command"/>
</bean>
在上面的例子中,标识为commandManager的bean在需要一个新的command bean实例时,会调用createCommand方法。重要的一点是,必须将command部署为prototype。当然也可以指定为singleton,如果是这样的话,那么每次将返回相同的command bean实例!
我做了个例子
目录结构


需要asm.jar和cglib.jar,cglib的版本会依赖对应的版本号,如果发现了asm和cglib的错误,可以换版本试试
package com.liyixing.spring.service;
public interface IAccountService {
public void getAccount();
}
package com.liyixing.spring.service;
public interface IDownloadService {
public void getDownload();
}
package com.liyixing.spring.service.imp;
import com.liyixing.spring.service.IDownloadService;
public class DownloadService implements IDownloadService {
public void getDownload() {
System.out.println("getDownload()");
}
}
package com.liyixing.spring.service.imp;
import com.liyixing.spring.service.IAccountService;
import com.liyixing.spring.service.IDownloadService;
public abstract class AccountService implements IAccountService {
private IDownloadService downloadService;
public IDownloadService getDownloadService() {
return downloadService;
}
public void setDownloadService(IDownloadService downloadService) {
this.downloadService = downloadService;
}
public void getAccount() {
downloadService = look();
downloadService.getDownload();
System.out.println("getAccount()");
System.out.println("down is " + downloadService);
System.out.println();
}
public abstract IDownloadService look();
}
这个类是抽象类,它的look方法也是抽象方法;
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-2.5.xsd">
<bean id="accountService" class="com.liyixing.spring.service.imp.AccountService">
<lookup-method name="look" bean="downloadService"/>
</bean>
<bean id="downloadService" class="com.liyixing.spring.service.imp.DownloadService"
scope="prototype">
</bean>
</beans>
<lookup-method name="look" bean="downloadService"/>这里设置了方法,并设置的bean属性这个属性表示将会以在look方法,返回downloadService这个类,类似的在look的动态生成的代码会有
beanFactory.getBean("downloadService");方法存在。
请注意,为了让这个动态子类得以正常工作,需要把CGLIB的jar文件放在classpath里。另外,Spring容器要子类化的类不能是final的,要覆盖的方法也不能是final的。同样的,要测试一个包含抽象方法的类也稍微有些不同,你需要自己编写它的子类提供该抽象方法的桩实现。最后,作为方法注入目标的bean不能是序列化的(serialized)。
现ServiceLocatorFactoryBean(在org.springframework.beans.factory.config包里)的用法和ObjectFactoryCreatingFactoryBean的有些相似,不同的是它允许你指定自己的lookup接口,不一定非要用Spring的lookup接口,比如ObjectFactory。要详细了解这种方法请参考ServiceLocatorFactoryBean的Javadocs(它的确减少了对Spring的耦合)。
能够在HTTP request或者Session(甚至自定义)作用域中定义bean固然很好,但是Spring IoC容器除了管理对象(bean)的实例化,同时还负责协作者(或者叫依赖)的实例化。如果你打算将一个Http request范围的bean注入到另一个bean中,那么需要注入一个AOP代理来替代被注入的作用域bean。也就是说,你需要注入一个代理对象,该对象具有与被代理对象一样的公共接口,而容器则可以足够智能的从相关作用域中(比如一个HTTP request)获取到真实的目标对象,并把方法调用委派给实际的对象。
<aop:scoped-proxy/> 不能和作用域为singleton或prototype的bean一起使用。为singleton bean创建一个scoped proxy将抛出BeanCreationException异常。
让我们看一下将相关作用域bean作为依赖的配置,配置并不复杂(只有一行),但是对理解“为何这么做”以及“如何做”是很重要的。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<!-- a HTTP Session-scoped bean exposed as a proxy -->
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<!-- this next element effects the proxying of the surrounding bean -->
<aop:scoped-proxy/>
</bean>
<!-- a singleton-scoped bean injected with a proxy to the above bean -->
<bean id="userService" class="com.foo.SimpleUserService">
<!-- a reference to the proxied
'userPreferences' bean -->
<property name="userPreferences" ref="userPreferences"/>
</bean>
</beans>
要创建这样的代理,只需要在Bean作用域定义中增加一个<aop:scoped-proxy/>子元素(为了让容器可以有效的使用基于类(而不是接口)的代理,你需要在classpath中加入CGLIB包, 并且要使用Appendix A, XML Schema-based configuration配置方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
这引入的xsi的aopxsd文件
)。为什么在request,session, globalSession 和 '自定义作用域' 需要<aop:scoped-proxy/>元素?在下面配置片段中可以找到解释(注意下面 'userPreferences' Bean定义是不完整的):
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
从上述配置中可以很明显的看到singleton bean userManager被注入了一个指向HTTP Session作用域bean userPreferences的引用。singleton userManager bean会被容器仅实例化一次,并且其依赖(即userPreferences bean)也仅被注入一次。这意味着,userManager在理论上只会操作同一个userPreferences对象,即原先被注入的那个bean。而注入一个HTTP Session作用域的bean作为依赖,有违我们的初衷。因为我们想要的只是一个userManager对象,在它进入一个HTTP Session生命周期时,我们希望去使用一个HTTP Session的userPreferences对象。
当注入某种类型对象时,该对象实现了和UserPreferences类一样的公共接口(即UserPreferences实例)。并且不论我们底层选择了何种作用域机制(HTTP request、Session等等),容器都会足够智能的获取到真正的 UserPreferences对象,因此我们需要将该对象的代理注入到userManager bean中, 而userManager bean并不会意识到它所持有的是一个指向UserPreferences引用的代理。在本例中,当UserManager实例调用了一个使用UserPreferences对象的方法时,实际调用的是代理对象的方法。随后代理对象会从HTTP Session获取真正的UserPreferences对象,并将方法调用委派给获取到的实际的UserPreferences对象。
这就是当把request-, session-, 和 globalSession-scoped beans 注入到协作对象中时,需要以下的正确而完整的配置:
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
选择创建代理的类型
默认情况下,当一个bean有<aop:scoped-proxy/>标记时,Spring容器将为它创建一个基于CGLIB的类代理,这意味着你需要 将CGLIB库添加到应用的classpath中。
注意:CGLIB代理仅仅拦截public方法的调用!对于非public的方法调用,不会对目标对象产生委托。
你可以将<aop:scoped-proxy/>的属性'proxy-target-class'设置为'false'来选择标准JDK推荐的基于接口的代理,这样就不需要在应用的classpath中增加额外的库。但是,这就意味着类必须实现至少一个接口。并且所有的协作者必须通过某一个 接口来引用bean。
发表评论
-
Spring 定时任务,cron表达式,@Scheduled cron表达式
2016-04-25 15:48 5324一个cron表达式有至少6 ... -
spring mvc list
2015-12-14 10:28 1304我使用这样无法传入 @requestMapping(" ... -
Unable to locate Spring NamespaceHandler for XML schema namespace
2015-09-23 14:00 2345org.springframework.beans.facto ... -
关于使用s.url jstl的上下文
2015-08-16 13:28 941比如 [@s.url '/'/]index.html?cote ... -
Spring 属性占位符配置器 PropertyPlaceholderConfigurer
2015-08-02 12:43 2104<!-- 属性配置文件读 ... -
FactoryBean接口
2014-09-30 14:05 925实现了FactoryBean接口的bean不是简单的一个bea ... -
国际化之MessageSourceAware和MessageSourceAccessor
2014-01-06 23:13 2882先看接口MessageSourceAware 该接口的注释中 ... -
spring 惯例优先原则
2013-07-22 09:46 1234惯例优先原则(convention over configur ... -
ant path匹配
2013-07-22 09:40 2196spring和ant path实现相关的主要类有两个 org. ... -
springmvc action方法中参数具有@ModelAttribute与不具有的区别
2012-12-14 09:36 4146在springmvc的参数解析中,发现具有@ModelAttr ... -
util包
2012-12-05 13:50 1131spring的util基本上都在springframework ... -
url,请求相关帮助类UrlPathHelper
2012-11-29 11:18 2550org.springframework.web.util.Ur ... -
整站国际化方案
2012-11-28 17:46 1129当前常见的实现方式,主要由两种方案实现 1.通过locale ... -
spring的三种注入方式
2012-11-20 17:30 18841.通过bean的property子元 ... -
spring AnnotationUtils 注解工具
2011-12-08 11:27 1323spring AnnotationUtils 注解工具 -
GenericCollectionTypeResolver,用于获取list或者map等元素的类型
2011-12-07 16:17 1329GenericCollectionTypeResolver,用 ... -
属性编辑器
2011-12-05 18:19 1096我自定义了一个类型,然后设置了一个属性编辑器,注册的class ... -
iframe下面的session问题
2011-12-04 19:52 5353在写iframe完成长连接获取上传状态的时候,有两次请求,一次 ... -
mvc之类的驱动原理
2011-12-01 09:34 1119<mvc:annotation-driven /> ... -
Couldn't access current invocation
2011-10-20 20:44 1919做了一个aop的日志记录器,但是在运行的时候出现了日志信息 服 ...
相关推荐
2. scope: true —— 创建一个新的隔离作用域,这个作用域会继承父作用域的属性和方法。不过,这个继承是单向的,即父作用域中的数据变化可以影响到子作用域,而子作用域中的数据变化不会影响到父作用域。这种配置...
在Spring框架中,注解注入是一种非常常用且强大的依赖注入(Dependency Injection,简称DI)方式。依赖注入是Spring的核心特性之一,它允许开发者在不直接创建对象的情况下,将依赖关系从对象代码中分离出来,提高了...
它主要利用了几个核心概念来构建动态网页应用:双向数据绑定、依赖注入、指令、作用域(Scopes)、过滤器和模块等。 ####作用域(Scopes) - **作用域的概念:** 作用域是模型视图之间的桥梁,是应用数据和视图...
所有AngularJS内置的服务、作用域方法以及其他API都有一个'$'前缀。这是一个约定俗成的规则,旨在避免命名冲突。因此,开发者在命名自定义服务和模型时,应避免使用'$'前缀,以防止与AngularJS的内置API发生命名冲突...
基本用法包括定义绑定源和目标,同时避免冲突,例如通过指定作用域,以防止多个组件监听相同的数据。Pasley提供了全局、局部等多种作用域,以便于管理和组织绑定。 1. **持久化属性**:发布(publish)的属性可以...
Spring的配置方式有XML和注解两种,XML配置中,可以定义Bean的属性、作用域、依赖关系等;注解配置则更简洁,通过在类或方法上添加注解实现配置。 依赖注入(Dependency Injection,DI)是Spring的重要特性,它允许...
总的来说,这份AngularJS学习笔记系统地介绍了AngularJS的基本概念和特性,从基本的视图绑定、依赖注入、作用域,到高级的自定义模块、指令、路由管理等,为学习者提供了一份全面的学习材料。这份笔记记录了学习者的...
AngularJS的概念众多,包括组件、服务、依赖注入、作用域、数据绑定等。下面详细解释这些AngularJS的核心概念,并通过示例代码进行展示。 一、组件(Components) 组件是AngularJS应用程序中的基本构建块,它们负责...
使用Block或Closure可以局部地管理对象,将对象的创建和使用限制在特定的作用域内。这有助于避免全局状态,减少潜在的冲突。 8. **KVO(Key-Value Observing)与通知中心(NotificationCenter)** 通过KVO或...
Java是一种广泛使用的面向对象的... - 全局作用域(静态导入):在整个程序中都可见,但不推荐,可能导致命名冲突。 理解这些Java面试题的关键知识点有助于深入掌握Java开发和系统架构,并在面试中表现出专业水平。
这需要仔细的规划,以确保作用域的继承与内容的transclude不会相互冲突。 在AngularJS中使用transclude功能,不仅需要理解其基本概念,还需要掌握在实际应用中的技巧和注意事项。虽然transclude为AngularJS增加了...
对于复杂的应用,显式装配(如使用@Bean或@Autowired注解)可以提供更细粒度的控制,允许你指定bean之间的依赖关系,包括依赖的顺序、作用域等。 6. **性能影响**: 自动装配需要Spring容器进行额外的工作来识别和...
Spring框架是Java开发中不可或缺的一部分,它以其强大的依赖注入(DI)和面向切面编程(AOP)功能闻名。在面试中,理解Spring的核心概念和技术是至关重要的。以下是对Spring框架的一些关键知识点的详细说明: 1. ...
5. 服务和工厂:AngularJS的服务和工厂是管理和封装应用中数据和功能的组件,它们是依赖注入系统中的重要角色,允许在不同的控制器和指令间共享数据和方法。 接下来,详细解释上述提到的几个编程思想: - 数据绑定...
这与@Autowired配合使用,帮助解决多bean注入的冲突。 7. **@Profile** `@Profile`注解允许你在不同环境(如开发、测试、生产)中使用不同的bean配置。你可以指定bean应该在哪些配置环境下激活。 8. **@...
若请求参数名与方法参数名不一致,可以通过`value`属性指定映射关系。 7. **@ModelAttribute**:多用途注解,可标记在方法上,用于在处理请求前预填充模型数据,或者标记在方法参数上,从模型中提取数据。在控制器...
- **作用域与闭包**:掌握变量的作用域规则,理解函数作用域和块级作用域,以及闭包的原理和应用。 - **原型与继承**:了解JavaScript的原型链机制,以及如何实现对象的继承。 - **事件与DOM操作**:熟悉DOM树的...
- **Bean 概述**:Bean 是 Spring 容器管理的对象,具有一定的生命周期和作用域。 - **命名 Bean**:可以通过 ID 或名称来唯一标识一个 Bean。 - **别名**:可以在容器中为 Bean 定义别名,以便更容易地引用它。 ...
2. 利用自定义元素microapp作为容器,实现微应用的样式隔离和JS作用域隔离。 3. 采用发布订阅模式,实现主应用与微应用之间的数据交互。 ### 功能特点 1. 渲染子应用加载远程HTML,解析DOM获取JS、CSS静态资源完成...
- **setter 方法注入**:通过 setter 方法注入依赖项。 - **字段注入**:直接在字段上使用注解来注入依赖项。 ### Spring Beans #### Spring Beans 定义 - **什么是 Spring Beans?** - Spring Beans 是由 ...