Spring 進階(7) 使用註解配置bean(3)
阿新 • • 發佈:2018-12-10
- 這裡主要介紹自動裝配和精確裝配
- 自動裝配可以通過@Autowired註解,被這個註解修飾的方法會在容器中找和id和引數名字一樣的bean,然後把它裝配進去。需要 指出的是,當容器中有大於一個bean符合條件的話,會丟擲異常,當有大於一個bean符合條件的話,spring什麼也不做。
package InstanceClass; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; //同上 @Lazy(false) @Component public class ClassB { private String name; private ClassC classC; public ClassC getClassC() { return classC; } @Autowired public void setClassC(ClassC classC) { this.classC = classC; } void setName(String name) { this.name = "ok1"; } public void thisIsMyName(){ System.out.println("B' s name is " + name); } @PostConstruct public void init(){ System.out.println("It is B's init"); } public String getName() { return name; } @PreDestroy public void destory(){ System.out.println("It is B's destory"); } }
package InstanceClass; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class ClassC { @Value("classC") private String name; public String getName() { return name; } }
package TestPackage; import InstanceClass.ClassA; import InstanceClass.ClassB; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; //測試類 public class SpringTest { public static void main(String []args){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); ClassA classA = applicationContext.getBean("classA", ClassA.class); System.out.println(classA.toString()); classA = applicationContext.getBean("classA", ClassA.class); System.out.println(classA.getClassB().getName()); ClassB classB = applicationContext.getBean("classB", ClassB.class); System.out.println(classB.getClassC().getName()); ((ClassPathXmlApplicationContext) applicationContext).registerShutdownHook(); } }
<?xml version="1.0" encoding="GBK"?> <!--要使用註解的話,就要先引入對應的配置--> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!--顯式指定要在那個路徑下自動配置bean--> <context:component-scan base-package="InstanceClass"/> </beans>
執行測試類看到結果
It is B's init [email protected] null classC It is B's destory
可以看到,spring把classC當作引數傳進去了
-
自動裝配還允許有多個引數
@Autowired public void setClassCAndClassD(ClassC classC , ClassD classD) { this.classC = classC; this.classD = classD; }
測試類
package TestPackage; import InstanceClass.ClassA; import InstanceClass.ClassB; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; //測試類 public class SpringTest { public static void main(String []args){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); ClassA classA = applicationContext.getBean("classA", ClassA.class); System.out.println(classA.toString()); classA = applicationContext.getBean("classA", ClassA.class); System.out.println(classA.getClassB().getName()); ClassB classB = applicationContext.getBean("classB", ClassB.class); System.out.println(classB.getClassC().getName() + "," + classB.getClassD().getName()); ((ClassPathXmlApplicationContext) applicationContext).registerShutdownHook(); } }
輸出
It is B's init [email protected] null classC,classD It is B's destory
-
還不止這樣呢,對於在額按中定義的陣列。入股使用自動裝配註解修飾的話,spring還會去本容器中找到所有和被修飾的陣列的類(包括他的子類)去填充這個陣列。程式碼如下
-
先把ClassC和ClassD定義成interface的實現類
-
在ClassB中用自動裝配修飾interface陣列
@Autowired private Interface[] interfaces;
-
測試類,可以看到interfaces陣列的長度為2
-
在classB中
@PreDestroy public void destory(){ System.out.println("It is B's destory"); System.out.println(interfaces.length); }
-
測試類中
((ClassPathXmlApplicationContext) applicationContext).registerShutdownHook();
d
-
-
當Autowired修飾了set方法,spring就會在指定的路徑去尋找符合條件的bean把他填充進去,但是,當指定的路徑下有不止一個bean符合條件的時候,spring就會不知道怎麼辦了,畢竟它只是一個spring,這是應該在符合的bean中,將其中的一個作為候選bean,這樣spring就會把它填充進去啦~
private Interface interface1; //ClassC 和ClassD都是Interface的子類,所以這裡就有不止一個bean符合條件。 public Interface getInterface1() { return interface1; } @Autowired public void setInterface1(Interface interface1) { this.interface1 = interface1; }
@Component @Primary //當把ClassC用Primary註解以後,spring就會知道應該把ClassC填進去啦 public class ClassC implements Interface { @Value("classC") private String name; public String getName() { return name; } }
-
- 自動裝配可以通過@Autowired註解,被這個註解修飾的方法會在容器中找和id和引數名字一樣的bean,然後把它裝配進去。需要 指出的是,當容器中有大於一個bean符合條件的話,會丟擲異常,當有大於一個bean符合條件的話,spring什麼也不做。