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”時要確?!發azyinitDi”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 李凡 閱讀(165) | 評論 (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 李凡 閱讀(148) | 評論 (0)編輯 收藏



          已有 1 人發表留言,猛擊->>這里<<-參與討論


          ITeye推薦



          posted @ 2012-10-17 16:14 李凡 閱讀(126) | 評論 (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 李凡 閱讀(154) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 都江堰市| 淮滨县| 廊坊市| 绍兴市| 桃江县| 靖州| 顺平县| 福建省| 大冶市| 博乐市| 孟村| 墨竹工卡县| 荆门市| 河池市| 宣汉县| 新宁县| 苏州市| 耿马| 沾益县| 西林县| 宾阳县| 庄河市| 拉孜县| 云和县| 永仁县| 吉林市| 庆城县| 获嘉县| 易门县| 维西| 增城市| 澜沧| 江山市| 偃师市| 天水市| 库车县| 航空| 永安市| 福州市| 友谊县| 太仓市|