- 浏览: 425959 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
pulsar_lxl:
请注明转载原文:http://hllvm.group.itey ...
JVM研究 -
goycejin:
感谢楼主,我也要及笔记了,这记性
Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:2.8.1:jar -
lianglong2000:
我理解是 java -server 类名 是运行的jdk中的j ...
jdk,jre你真的懂吗? -
yanqlv:
有个问题,既然windows目录(Windows/system ...
jdk,jre你真的懂吗? -
yanqlv:
系统化的描述也挺重要,架构模式>设计模式,架构模式≈设计 ...
MVC是设计模式么?是框架么?
Spring使用CGLIB的动态字节码增强功能,所以,必须要加入CGLIB包
当Bean依赖另一个生命周期不同的bean,尤其是当singleton依赖一个non-singleton时,常会遇到不少问题,Lookup Method Injection正是对付这些问题而出现的,在上述情况中,setter和构造注入都会导致singleton去维护一个non-singleton bean的单个实例,某些情况下,我们希望让singleton bean每次要求获得bean时候都返回一个non-singleton bean的新实例
当一个singleton bean A 在每次方法调用的时候都需要一个non-singleton bean B,此时就会产生这样一个问题,因为A为singleton,所以容器只会创建一次A,那么也只有一次机会来创建A的属性,Bean B也只能被初始化一次,但是我们调用每个方法的时候又都需要一个新的B的实例。通常的时候我们只要new一个就可以,但在Spring中这不符合整体性的设计,这样就有了方法注入。
让我们开始一个简单的测试。
在你的工程的根目录中分别建立一个src,classes,lib文件夹。此次我们将采用Ant来进行部署。
在src中建立Random.java,HelloRandom.java,HelloAbstract.java,Test.java。代码如下。
Random.java这是一个可以产生随机数的类,很简单。
package com.testspring.basic.lookup;
public class Random {
private int num = (int)(100*Math.random());
public void printRandom(){
System.out.println("随机数是"+num);
}
}
HelloRandom.java一个代理接口。
package com.testspring.basic.lookup;
public interface HelloRandom {
public Random getRandom();
public abstract Random createRandom(); //这个方法最为重要,是方法注入的关键
}
HelloAbstract.java
package com.testspring.basic.lookup;
public abstract class HelloAbstract implements HelloRandom{
private Random random;
public void setRandom(Random random){
this.random = random;
}
public Random getRandom(){
return this.random;
}
public abstract Random createRandom();
}
Test.java用于测试
package com.testspring;
import org.springframework.context.ApplicationContext;
import com.testspring.basic.lookup.*;
public class Test {
public static void main(String[] args) {
try{
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
HelloRandom helloRandom = (HelloRandom)context.getBean("helloRandom");
System.out.println("下面两个实例没有采用方法注入");
Random r1 = helloRandom.getRandom();
Random r2 = helloRandom.getRandom();
System.out.println("Random 的两个实例是否指向同一个引用:" + (r1 == r2));
r1.printRandom();
r2.printRandom();
System.out.println();
System.out.println("下面两个实例采用方法注入");
Random r3 = helloRandom.createRandom();
Random r4 = helloRandom.createRandom();
System.out.println("Random 的两个实例是否指向同一个引用:" + (r3 == r4));
r3.printRandom();
r4.printRandom();
}catch(Exception e){
e.printStackTrace();
}
}
}
在src中建立一个bean.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- 方法注入-->
<bean id="myRandom" class="com.testspring.basic.lookup.Random" scope="prototype" />
<bean id="helloRandom" class="com.testspring.basic.lookup.HelloAbstract">
<lookup-method name="createRandom" bean="myRandom"/>
<property name="random">
<ref local="myRandom" />
</property>
</bean>
</beans>
在根目录中建立一个build.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project name="MySpring" default="run" basedir=".">
<!-- 全局变量的定义 -->
<property name="src.dir" value="src" /> <!-- 源文件位置 -->
<property name="classes.dir" value="classes" /> <!-- class文件位置 -->
<property name="lib.dir" value="lib" /> <!-- 引用的jar文件位置 -->
<!--当前工程环境变量-->
<path id="Project-Classpath">
<pathelement path="${classes.dir}"/>
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
</path>
<!--编译-->
<target name="compile" depends="clean">
<javac srcdir="${src.dir}" destdir="${classes.dir}">
<classpath refid="Project-Classpath" />
</javac>
</target>
<!--复制除了java文件以外的文件-->
<target name="copy-resources" depends="compile">
<copy todir="${classes.dir}">
<fileset dir="${src.dir}">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
<!--运行-->
<target name="run">
<java fork="true" classname="com.testspring.Test">
<classpath refid="Project-Classpath" />
</java>
</target>
</project>
将spring.jar,cglib-nodep-2.1_3.jar放入lib中。
运行build命令就可以看到我们的结果了
----------------------------------------------------------------------------------------------
下面两个实例没有采用方法注入
Random 的两个实例是否指向同一个引用:true
随机数是99
随机数是99
下面两个实例采用方法注入
Random 的两个实例是否指向同一个引用:false
随机数是98
随机数是17
注意事项:
1.应用场合:一个singleton的Bean需要引用一个prototype的Bean; 一个无状态的Bean需要引用一个有状态的Bean; ... ; 等等情景下.
2.假定你有三个singleton,公用一个依赖,希望每个singleton有自己的实例依赖,所以将依赖设置成singleton,但
实际上每个singleton在其生命周期中使用协作着的同一个实例足以,这种情况下,setter是最好的选择,使用方
法查找注入会增加不必要的开销
3.我们也可以使用实现BeanFactoryAware的方式代替Lookup Method Injection
public void setBeanFactory(Beanfactory factory){
this.factory=factory;
}
public Random createRandom(){
return (Random)factory.getBean("myRandom");
}
使用上述方法在效率上和使用本例的方法,相差无几(100000次差别在几毫秒),所以,建议使用本里的方法,减少和spring api的耦合
4.尽管可以不把查找方法定义成abstract,但还是建议这样做,可以防止不小心忘了配置查找方法而留一个空方法在代码中
5. 记住在任何时候只要定义了一个Bean的Lookup方法,那么这个Bean的实例将是一个CGLIB动态生成的实例而不是原来类的实例。
6.Spring允许在一个Bean中定义多个Lookup方法。
7.Spring还允许Lookup方法中定义的方法带有参数,但是Sping不会处理这些参数。
8.Spring对Lookup方法也存在一些限制:
方法不能是private的,但可以是protected的。
方法不能是静态的。
当Bean依赖另一个生命周期不同的bean,尤其是当singleton依赖一个non-singleton时,常会遇到不少问题,Lookup Method Injection正是对付这些问题而出现的,在上述情况中,setter和构造注入都会导致singleton去维护一个non-singleton bean的单个实例,某些情况下,我们希望让singleton bean每次要求获得bean时候都返回一个non-singleton bean的新实例
当一个singleton bean A 在每次方法调用的时候都需要一个non-singleton bean B,此时就会产生这样一个问题,因为A为singleton,所以容器只会创建一次A,那么也只有一次机会来创建A的属性,Bean B也只能被初始化一次,但是我们调用每个方法的时候又都需要一个新的B的实例。通常的时候我们只要new一个就可以,但在Spring中这不符合整体性的设计,这样就有了方法注入。
让我们开始一个简单的测试。
在你的工程的根目录中分别建立一个src,classes,lib文件夹。此次我们将采用Ant来进行部署。
在src中建立Random.java,HelloRandom.java,HelloAbstract.java,Test.java。代码如下。
Random.java这是一个可以产生随机数的类,很简单。
package com.testspring.basic.lookup;
public class Random {
private int num = (int)(100*Math.random());
public void printRandom(){
System.out.println("随机数是"+num);
}
}
HelloRandom.java一个代理接口。
package com.testspring.basic.lookup;
public interface HelloRandom {
public Random getRandom();
public abstract Random createRandom(); //这个方法最为重要,是方法注入的关键
}
HelloAbstract.java
package com.testspring.basic.lookup;
public abstract class HelloAbstract implements HelloRandom{
private Random random;
public void setRandom(Random random){
this.random = random;
}
public Random getRandom(){
return this.random;
}
public abstract Random createRandom();
}
Test.java用于测试
package com.testspring;
import org.springframework.context.ApplicationContext;
import com.testspring.basic.lookup.*;
public class Test {
public static void main(String[] args) {
try{
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
HelloRandom helloRandom = (HelloRandom)context.getBean("helloRandom");
System.out.println("下面两个实例没有采用方法注入");
Random r1 = helloRandom.getRandom();
Random r2 = helloRandom.getRandom();
System.out.println("Random 的两个实例是否指向同一个引用:" + (r1 == r2));
r1.printRandom();
r2.printRandom();
System.out.println();
System.out.println("下面两个实例采用方法注入");
Random r3 = helloRandom.createRandom();
Random r4 = helloRandom.createRandom();
System.out.println("Random 的两个实例是否指向同一个引用:" + (r3 == r4));
r3.printRandom();
r4.printRandom();
}catch(Exception e){
e.printStackTrace();
}
}
}
在src中建立一个bean.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- 方法注入-->
<bean id="myRandom" class="com.testspring.basic.lookup.Random" scope="prototype" />
<bean id="helloRandom" class="com.testspring.basic.lookup.HelloAbstract">
<lookup-method name="createRandom" bean="myRandom"/>
<property name="random">
<ref local="myRandom" />
</property>
</bean>
</beans>
在根目录中建立一个build.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project name="MySpring" default="run" basedir=".">
<!-- 全局变量的定义 -->
<property name="src.dir" value="src" /> <!-- 源文件位置 -->
<property name="classes.dir" value="classes" /> <!-- class文件位置 -->
<property name="lib.dir" value="lib" /> <!-- 引用的jar文件位置 -->
<!--当前工程环境变量-->
<path id="Project-Classpath">
<pathelement path="${classes.dir}"/>
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
</path>
<!--编译-->
<target name="compile" depends="clean">
<javac srcdir="${src.dir}" destdir="${classes.dir}">
<classpath refid="Project-Classpath" />
</javac>
</target>
<!--复制除了java文件以外的文件-->
<target name="copy-resources" depends="compile">
<copy todir="${classes.dir}">
<fileset dir="${src.dir}">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
<!--运行-->
<target name="run">
<java fork="true" classname="com.testspring.Test">
<classpath refid="Project-Classpath" />
</java>
</target>
</project>
将spring.jar,cglib-nodep-2.1_3.jar放入lib中。
运行build命令就可以看到我们的结果了
----------------------------------------------------------------------------------------------
下面两个实例没有采用方法注入
Random 的两个实例是否指向同一个引用:true
随机数是99
随机数是99
下面两个实例采用方法注入
Random 的两个实例是否指向同一个引用:false
随机数是98
随机数是17
注意事项:
1.应用场合:一个singleton的Bean需要引用一个prototype的Bean; 一个无状态的Bean需要引用一个有状态的Bean; ... ; 等等情景下.
2.假定你有三个singleton,公用一个依赖,希望每个singleton有自己的实例依赖,所以将依赖设置成singleton,但
实际上每个singleton在其生命周期中使用协作着的同一个实例足以,这种情况下,setter是最好的选择,使用方
法查找注入会增加不必要的开销
3.我们也可以使用实现BeanFactoryAware的方式代替Lookup Method Injection
public void setBeanFactory(Beanfactory factory){
this.factory=factory;
}
public Random createRandom(){
return (Random)factory.getBean("myRandom");
}
使用上述方法在效率上和使用本例的方法,相差无几(100000次差别在几毫秒),所以,建议使用本里的方法,减少和spring api的耦合
4.尽管可以不把查找方法定义成abstract,但还是建议这样做,可以防止不小心忘了配置查找方法而留一个空方法在代码中
5. 记住在任何时候只要定义了一个Bean的Lookup方法,那么这个Bean的实例将是一个CGLIB动态生成的实例而不是原来类的实例。
6.Spring允许在一个Bean中定义多个Lookup方法。
7.Spring还允许Lookup方法中定义的方法带有参数,但是Sping不会处理这些参数。
8.Spring对Lookup方法也存在一些限制:
方法不能是private的,但可以是protected的。
方法不能是静态的。
发表评论
-
Java线程池使用说明
2015-05-12 23:34 1217一简介 线程的使用在java中占有极其重要的地位 ... -
Long == 操作符 的陷阱
2015-02-25 10:38 831当两个对象进行比较的时候,我们应该使用equals方法,但是 ... -
java中只有值传递,没有引用传递
2013-08-24 14:29 1423一、首先来明确一下"值传递"和&quo ... -
java vs javaw vs javaws
2013-08-12 22:54 1424reference:http://javapapers.co ... -
java类的初始化顺序
2013-07-17 23:14 763(1)加载父类(以下序号相同,表明初始化是按代码从上到下的顺序 ... -
java泛型
2013-07-04 11:43 1051泛型是Java SE 1.5的新特性,泛型的本质是参数化类 ... -
JVM分代垃圾回收详述
2013-07-03 20:15 873虚拟机中的共划分为三 ... -
JSP 9 大内置对象详解
2013-06-24 23:15 1093内置对象特点:1. 由JSP规范提供,不用编写者实例化2. ... -
什么是J2EE
2013-05-20 19:36 1255J2EE英文全称Java 2 Platform Enterpr ... -
transient Volatile ThreadLocal
2013-04-29 16:05 1229Java的serialization提供了 ... -
java 过滤器 Filter
2012-10-11 14:43 1444Servlet 过滤器是可插入 ... -
java xml解析
2012-08-04 17:11 1691随着XML越来越广泛地被 ... -
Tomcat Web项目中文乱码问题解决方案
2012-07-30 16:58 2828Tomcat常见乱码解决方案:(建议按顺序来看,逐个排除) 1 ... -
list的remove问题
2012-07-17 12:45 17421、增强的for循环里面不 ... -
java方法覆盖的原则
2012-06-06 22:50 1784什么是方法覆盖 如果在子类中定义的一个方法,其名称、返回类型 ... -
继承中的构造方法及覆盖与隐藏
2012-06-06 22:27 2165继承中的构造方法 一、 ... -
java虚拟机内存原型
2012-05-14 17:21 1038寄存器:我们在程序中无法控制 栈:存放基本类型的数据和对象的引 ... -
jdk,jre你真的懂吗?
2012-05-07 11:01 24090关于jdk和jre 大家肯定 ... -
java注解
2012-04-24 16:56 1469Java注解 一、什么是java注解 注 ... -
java
2012-03-16 19:50 8580. 构造方法不能被继承! 1. ...
相关推荐
“Lookup方法”可以使Spring替换一个bean原有的,获取其它对象具体的方法,并自动返回在容器中的查找结果。下面这篇文章主要给大家介绍了关于Spring中Lookup(方法注入)的相关资料,需要的朋友可以参考下
Spring系列第12篇:lazy-init:bean延迟初始化Spring系列第13篇:使用继承简化bean配置(abstract & parent)Spring系列第14篇:lookup-method和replaced-method比较陌生,怎么玩的?Spring系列第15篇:代理详解(Java...
requestUtils lookup方法简介
Ofbiz的Lookup字段,讲解ofbiz辅助输入,包括文本,选择框,日期,时间,主从文本框。后面还介绍一下自定义修改的Lookup
如何使用Spring从JNDI查找数据源 Server.xml <资源名称=“ jdbc / javatechie”全局=“ jdbc / javatechie” auth =“容器” type =“ javax.sql.DataSource” driverClassName =“ com.mysql.jdbc.Driver” url...
【亲测可用】Revit 2020 Lookup Tables是Revit表格查找工具,是revit开发必不可少的一个组件,需要的朋友可以下载! 用法:将RevitLookup.addin和RevitLookup.dll放到C:\ProgramData\Autodesk\Revit\Addins\2019下...
Lookup方法注入 3.3.8.2. 自定义方法的替代方案 3.4. bean的作用域 3.4.1. Singleton作用域 3.4.2. Prototype作用域 3.4.3. 其他作用域 3.4.3.1. 初始化web配置 3.4.3.2. Request作用域 3.4.3.3. Session作用域 3.4...
其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的...
vc错误查看工具lookup vc错误查看工具lookup
4.5.1 lookup方法注入 4.5.2 方法替换 4.6 之间的关系 4.6.1 继承 4.6.2 依赖 4.6.3 引用 4.7 整合多个配置文件 4.8 Bean作用域 4.8.1 singleton作用域 4.8.2 prototype作用域 4.8.3 Web应用环境相关的Bean作用域 ...
RevitLookup-2021.0.0.13,供各位做REVIT二次开发的同仁们下载、学习、研究。
Revit2018的Lookup
informatica lookup 组件使用案例
Revit二次开发必助插件revit lookup,辅助开发人员查看revit内部结构。方便开和学习内部结构
revit开发必备工具 本包中是已经编译过的文件,可以直接使用 ...编辑其中RevitLookup.dll 路径为编译路径 C:\RevitLookup-2016.0.0.6\CS\bin\Debug\RevitLookup.dll 重启revit: 即可在菜单栏看到工具
详解lookup滤镜原理及用法,Lookup是基于图片颜色映射的一种滤镜,它可以实现各种各样的效果。
Revit 2018 Lookup Tables顾名思义就是Revit表格查找工具,revit二次开发是离不开这个按钮的,由于revit中管件和线管配件族的尺寸参数会随着公称直径的变化而变化,revit可以通过这个按钮来实现这个功能,是revit...
excel 函数教程 lookup函数的经典查找使用方式
用NetBeans8.0做的的一个lookup查询的例子
LOOKUP函数处理内存数组,LOOKUP高级应用.