sblig

BlogJava 首页 新随笔 联系 聚合 管理
  10 Posts :: 0 Stories :: 0 Comments :: 0 Trackbacks

2012年10月16日 #

最后 遗留一个问题,继续探索中....

 

 

跟我学Spring3 学习笔记一

跟我学Spring3 学习笔记二

跟我学Spring3 学习笔记三

跟我学Spring3 学习笔记四

跟我学Spring3 学习笔记五 注入

跟我学Spring3 学习笔记六 注入

 

统一接口:

 

public interface HelloApi {
	public void sayHello();  
}

 

 

一、延迟初始化:

 

/**
 * 延迟初始化Bean
 *     延迟初始化也叫做惰性初始化,指不提前初始化Bean,而是只有在真正使用时才创建及初始化Bean。
 *     配置方式很简单只需在<bean>标签上指定 “lazy-init” 属性值为“true”即可延迟初始化Bean。
 */
public class DiLazyInit implements HelloApi{

	public void sayHello() {
		System.out.println("say DiInitDestory");
	}
	
	public DiLazyInit(){
		System.out.println("初始化 DiInitDestory");
	}
}

 

 

配置延迟初始化:

 

 

<!-- 延迟初始化Bean 
	     延迟初始化也叫做惰性初始化,指不提前初始化Bean,而是只有在真正使用时才创建及初始化Bean。
	     配置方式很简单只需在<bean>标签上指定 “lazy-init” 属性值为“true”即可延迟初始化Bean。 -->
	<bean id="lazyinitDi" class="com.diinit.DiLazyInit"
		lazy-init="true">
	</bean>

 

 junit 进行测试:

 

@Test
	public void testLazyInit(){
		ApplicationContext context = new ClassPathXmlApplicationContext("initdepends.xml");
		HelloApi lazyInit = context.getBean("lazyinitDi",HelloApi.class);
		lazyInit.sayHello();
		System.out.println("");
	}
 

 

注意这个时候的输出结果:

 

 

初始化 DiLazyInit

say DiLazyInit

 

 

 

 

二、 可以指定初始化和销毁的顺序

 

 

/* 使用depends-on 是指 指定Bean初始化及销毁时的顺序,使用depends-on属性指定的Bean要先初始化完毕
*     后才初始化当前Bean,由于只有“singleton”Bean能被Spring管理销毁,所以当指定的Bean都是“singleton”
*     时,使用depends-on属性指定的Bean要在指定的Bean之后销毁。
*     “decorator”指定了“depends-on”属性为“lazyinitDi”,所以在“decorator”Bean初始化之前要先初
*     始化“lazyinitDi”,而在销毁“lazyinitDi”之前先要销毁“decorator”,大家注意一下销毁顺序,与文档上的不符。
*     “depends-on”属性可以指定多个Bean,若指定多个Bean可以用“;”、“,”、空格分割。
*     
*  那“depends-on”有什么好处呢?
*     主要是给出明确的初始化及销毁顺序,比如要初始化“decorator”时要确保“lazyinitDi”Bean的资源准备好了,
*     否则使用“decorator”时会看不到准备的资源;而在销毁时要先在“decorator”Bean的把对“helloApi”资源的引用释
*     放掉才能销毁“lazyinitDi”,否则可能销毁 “lazyinitDi”时而“decorator”还保持着资源访问,造成资源不能释放或释放错误。
*/
public class ApiDecorator implements HelloApi{

	private HelloApi helloApi;
	
	public ApiDecorator(){
		System.out.println("初始化 ApiDecorator");
	}
	
	public void sayHello() {
		System.out.println("say ApiDecorator");
		helloApi.sayHello();
		
	}

	public HelloApi getHelloApi() {
		return helloApi;
	}

	public void setHelloApi(HelloApi helloApi) {
		this.helloApi = helloApi;
	}
}
 

 

配置xml指定初始化和销毁顺序:

 

<!-- 初始化及销毁时的顺序    
	     “decorator”指定了“depends-on”属性为“lazyinitDi”,所以在“decorator”Bean初始化之前
	     要先初始化“lazyinitDi”,而在销毁“lazyinitDi”之前先要销毁“decorator”,大家注意一下销毁顺序 -->
	<bean id="decorator" class="com.diinit.ApiDecorator"
		depends-on="lazyinitDi">
		<property name="helloApi">
			<ref bean="lazyinitDi" />
		</property>
	</bean>
 

 

 

 junit 进行测试:

 

@Test
	public void testLazyInit(){
		ApplicationContext context = new ClassPathXmlApplicationContext("initdepends.xml");
		HelloApi lazyInit = context.getBean("lazyinitDi",HelloApi.class);
		lazyInit.sayHello();
		System.out.println("");
	}
	
	@Test
	public void testDependsOn(){
		ApplicationContext context= new ClassPathXmlApplicationContext("initdepends.xml");
		HelloApi depends = context.getBean("decorator",HelloApi.class);
		depends.sayHello();
	}
 

 

注意这个时候的输出结果:

 

 

初始化 DiLazyInit

初始化 ApiDecorator            //也是上面同样的测试函数 testLazyInit(),同样的配置  这句是多打印出来的

say DiLazyInit

 

初始化 DiLazyInit

初始化 ApiDecorator

say ApiDecorator

say DiLazyInit


 

 

 

这突然多出来的打印结果,说明进行了ApiDecorator的对象的创建,

但是在第一个配置中也没涉及到 ApiDecorator 类的加载,注入  。

 

什么原因造成的呢?是一种隐藏的注入? 继续探索中....

 

 



已有 1 人发表留言,猛击->>这里<<-参与讨论


ITeye推荐



posted @ 2012-10-18 16:45 李凡 阅读(158) | 评论 (0)编辑 收藏


跟我学Spring3 学习笔记一

跟我学Spring3 学习笔记二

跟我学Spring3 学习笔记三

跟我学Spring3 学习笔记四

跟我学Spring3 学习笔记五 注入

 

 

引用其它Bean

 

一、构造器注入方式:

(1)通过” <constructor-arg>”标签的ref属性来引用其他Bean

 

(2)通过” <constructor-arg>”标签的子<ref>标签来引用其他Bean,使用bean属性来指定引用的Bean

二、setter注入方式:

(1)通过” <property>”标签的ref属性来引用其他Bean

(2)通过” <property>”标签的子<ref>标签来引用其他Bean,使用bean属性来指定引用的Bean

 

 

public class HelloDiBean implements HelloApi{

	private HelloApi helloApi;
	private HelloApi helloApi2;
	

	public HelloDiBean(HelloApi helloApi){
		this.helloApi = helloApi;
	}
	
	public void sayHello() {
		helloApi.sayHello();
		helloApi2.sayHello();
	}
	

	public HelloApi getHelloApi2() {
		return helloApi2;
	}

	public void setHelloApi2(HelloApi helloApi2) {
		this.helloApi2 = helloApi2;
	}
}

 配置注入引用其他的bean

 

<!-- 引用其他的bean进行注入 -->
	<bean id="helloBean" class="com.dilist.HelloDiBean">
		<constructor-arg index="0" ref="mapBean" />
		<property name="helloApi2">
			<ref bean="properBean" />
		</property>
	</bean>
	
 

其他引用bean 的高级用法:

 

/**
 * Spring还提供了另外两种更高级的配置方式,<ref local=””/>和<ref parent=””/>:
 * (1)<ref local=””/>配置方式:用于引用通过<bean id=”beanName”>方式中通过id属性指定的Bean,
 * 		它能利用XML解析器的验证功能在读取配置文件时来验证引用的Bean是否存在。
 * 		因此如果在当前配置文件中有相互引用的Bean可以采用<ref local>方式从而如果配置错误能在开发调试时就发现错误。
 * (2)<ref parent=””/>配置方式:用于引用父容器中的Bean,不会引用当前容器中的Bean,
 *       当然父容器中的Bean和当前容器的Bean是可以重名的,获取顺序是直接到父容器找。
 */
public class HelloHigh implements HelloApi{
	
	private HelloApi helloApi;
	private HelloApi helloApi2;
	

	public HelloHigh(HelloApi helloApi){
		this.helloApi = helloApi;
	}
	
	public void sayHello() {
		helloApi.sayHello();
		System.out.println("");
		helloApi2.sayHello();
	}
	

	public HelloApi getHelloApi2() {
		return helloApi2;
	}

	public void setHelloApi2(HelloApi helloApi2) {
		this.helloApi2 = helloApi2;
	}

}
 

helloworld.xml:

 

<!-- 注入properties类型 -->
	<bean id="properBean" class="com.dilist.HelloDiProperties">
		<property name="properties">
			<props value-type="int" merge="default"><!-- 虽然指定value-type,但是不起作用 -->
				<prop key="1">1sss</prop>           <!-- Properties 建和值都是String类型 -->
				<prop key="2">2</prop>
			</props>
		</property>
		<property name="properties2">
			<value> <!-- 分隔符可以是 “换行”、“;”、“,” 不建议该方式,优先选择第一种方式 -->
				1=11
				2=22;<!-- 这样的分隔符好像没用 -->
			    3=33,
				4=44
			</value>
		</property>
	</bean>

	<!-- Spring还提供了另外两种更高级的配置方式,<ref local=””/>和<ref parent=””/> -->
	<bean id="helloHigh" class="com.dilist.HelloHigh">
		<constructor-arg index="0"><ref local="properBean" /></constructor-arg>
		<property name="helloApi2"><ref parent="properBean" /></property>	
	</bean>
 

 

helloworldParent.xml:

 

<!-- 注入properties类型 -->
	<bean id="properBean" class="com.dilist.HelloDiProperties">
		<property name="properties">
			<props value-type="int" merge="default"><!-- 虽然指定value-type,但是不起作用 -->
				<prop key="1">2dss</prop>           <!-- Properties 建和值都是String类型 -->
				<prop key="2">3aas</prop>
			</props>
		</property>
		<property name="properties2">
			<value> <!-- 分隔符可以是 “换行”、“;”、“,” 不建议该方式,优先选择第一种方式 -->
				1=111
				2=222;<!-- 这样的分隔符好像没用 -->
			    3=333,
				4=444
			</value>
		</property>
	</bean>
 

调用处 利用加载父容器的方式,注入父容器中的Bean:

 

 

@Test
	public void testDiBeanHigh() {
		// 以classes为根目录算起
		// 读取配置文件实例化一个Ioc容器

		// 初始化父容器
		ApplicationContext parentContext = new ClassPathXmlApplicationContext(
				"helloworldParent.xml");

		// 初始化当前容器
		ApplicationContext context = new ClassPathXmlApplicationContext(
				new String[] { "helloworld.xml" }, parentContext);

		// 构造 + setter注入 引用其他的bean注入
		HelloApi helloApi = context.getBean("helloHigh", HelloApi.class);
		helloApi.sayHello();

	}


已有 0 人发表留言,猛击->>这里<<-参与讨论


ITeye推荐



posted @ 2012-10-18 14:32 李凡 阅读(141) | 评论 (0)编辑 收藏



已有 1 人发表留言,猛击->>这里<<-参与讨论


ITeye推荐



posted @ 2012-10-17 16:14 李凡 阅读(118) | 评论 (0)编辑 收藏

ASM 进行动态生成class
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class HelloWorld extends ClassLoader implements Opcodes{
	public static void main(String[] args) {
		ClassWriter cw = new ClassWriter(0);
		cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);
		MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
		mw.visitVarInsn(ALOAD, 0);
		mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
		mw.visitInsn(RETURN);
		mw.visitMaxs(1, 1);
		mw.visitEnd();
		
		mw = cw.visitMethod(ACC_PUBLIC+ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
		mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
		mw.visitLdcInsn("Hello World!");
		mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
		mw.visitInsn(RETURN);
		mw.visitMaxs(2, 2);
		mw.visitEnd(); 
		
		byte[] code = cw.toByteArray();
		FileOutputStream fos;
		try {
			fos = new FileOutputStream("Example.class");
			fos.write(code);
			fos.close();
			
			HelloWorld loader = new HelloWorld();   
		     Class exampleClass = loader   
		         .defineClass("Example", code, 0, code.length);  
				exampleClass.getMethods()[0].invoke(null, new Object[] { null });
				
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
}

 

cglib 动态生成class 并进行拦截

 

public class MyClass {
	public void print() {
		System.out.println("I'm in MyClass.print!");
	}
}


import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class Main {

	public static void main(String[] args) {

		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(MyClass.class);
		enhancer.setCallback((Callback) new MethodInterceptorImpl());
		MyClass my = (MyClass) enhancer.create();
		my.print();
	}

	private static class MethodInterceptorImpl implements MethodInterceptor {

		public Object intercept(Object obj, Method method, Object[] args,
				MethodProxy proxy) throws Throwable {
			// log something
			System.out.println(method + " intercepted!");

			proxy.invokeSuper(obj, args);
			return null;
		}

	}
}
 

已有 1 人发表留言,猛击->>这里<<-参与讨论


ITeye推荐



posted @ 2012-10-16 11:18 李凡 阅读(144) | 评论 (0)编辑 收藏