在配置bean时 默认bean的作用域是单例的 也就是scope = “singleton” 的,也就是在项目中只存在一个的 但是有时候为了配置不同的属性 需要在singleton中加入prototype的bean 这时候就会出现Bug 所以 要设置动态代理功能 此时要加入一个包在spring的cglib包
首先定义一个MyHelper类
package com.kevinswift.helper;
public class MyHelper {
//操作的内容
public void doSomethingHelper() {
}
}
在beans中 定义为一个prototype 的bean
新建一个java 接口
package com.kevinswift.helper;
public interface DemoBean {
MyHelper getHelper();
void someOperation();
}
新建一个standlookupDemo 实现接口 配置为singleton bean 并且依赖于作用域是prototype的myhelper 的bean
package com.kevinswift.helper;
public class standLookUpDemo implements DemoBean {
private MyHelper myhelper;
public MyHelper getMyhelper() {
return myhelper;
}
public void setMyhelper(MyHelper myhelper) {
this.myhelper = myhelper;
}
@Override
public MyHelper getHelper() {
// TODO Auto-generated method stub
return myhelper;
}
@Override
public void someOperation() {
// TODO Auto-gen erated method stub
myhelper.doSomethingHelper();
}
}
定义一个抽象类 并将getHelper方法定义为一个抽象方法 该方法的返回值为被依赖的bean为myhelper 同样实现接口
package com.kevinswift.helper;
public abstract class abstractLookUpDemo implements DemoBean {
//定义抽象方法 该方法由spring来实现
public abstract MyHelper getMyHelper();
@Override
public MyHelper getHelper() {
// TODO Auto-generated method stub
return getMyHelper();
}
@Override
public void someOperation() {
// TODO Auto-generated method stub
getMyHelper().doSomethingHelper();
}
}
随后详细来看bean的配置文件
<bean id = "helper" scope="prototype" class = "com.kevinswift.helper.MyHelper">
</bean>
<!-- 配置standLookUpHelper实例 -->
<bean id = "standLookUpBean" class = "com.kevinswift.helper.standLookUpDemo">
<property name="myhelper" ref = "helper"></property>
</bean>
<!-- 配置abstractlookupdemo 指定myHelper的方法返回helper实例 -->
<bean id = "abstractLookUpBean" class = "com.kevinswift.helper.abstractLookUpDemo">
<lookup-method name = "getMyHelper" bean="helper"/>
</bean>
这样即可完成将prototype类 注入到 singleton中
新建一个test 来进行判断
package com.kevinswift.helper;
import org.springframework.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.util.StopWatch;
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建容器
ApplicationContext ctx = new FileSystemXmlApplicationContext("src/beans.xml");
test.stressTest(ctx, "abstractLookUpBean");
test.stressTest(ctx, "standLookUpBean");
}
//获取两次的bean的实例 并比较是否为同一实例
public static void stressTest(ApplicationContext ctx,String beanName){
DemoBean bean = (DemoBean)ctx.getBean(beanName);
MyHelper helper1 = bean.getHelper();
MyHelper helper2 = bean.getHelper();
System.out.println("测试" + beanName);
System.out.println("helper是否相同" + (helper1 == helper2));
// StopWatch stopWatch = new StopWatch();
// //循环获取一万次bean的实例 并且调用bean的dosomethingHelperful的方法
// for(int i = 0 ; i < 10000; i++) {
// MyHelper helper = bean.getHelper();
// helper.doSomethingHelper();
//
// }
// stopWatch.stop();
// //计算获取10000次bean实例花费的执行时间
// System.out.println("获取10000次时间花费了 " + stopWatch.getLastTaskTimeMillis());
}
}
可以看出stand建出来是同一个的 而abstract建出来数不同的