Bản chất of Xuân is created the objects trong khung store of it for on các bạn cần thì có thể gọi to objects you need. Vì thế, mùa xuân tìm mọi cách to support for us be created the object trong khung store of it one cách dễ dàng nhất.
Us known cách khai báo to give the object to the objects khác, hay possible nói is give the object depends on the object bị phụ thuộc, bằng cách sử dụng thuộc tính ref, idref, danh sách ... Ngoài ra, mùa xuân còn hỗ trợ we give the object depends on the object bị phụ thuộc one cách tự động bằng cách sử dụng Bean Autowiring of it.
With the Bean Autowiring, chung ta ko needs to use thuộc tính ref , idref hay danh sách, which chỉ cần viết đang Tuân thủ theo quy tắc of mùa xuân thì đối tượng phụ thuộc will automatically be given to the object bị phụ thuộc.
Có ba cách to use Bean Autowiring, which is:
- bằng tên
- byType
- constructor
Để các bạn có thể hiểu rõ hơn, mình sẽ làm một ví dụ nhé! Trong ví dụ này mình sẽ yêu cầu Spring tự động đưa đối tượng Table vào đối tượng Room của mình. Cụ thể như sau:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class Room {
private Table table;
public Room(Table table) {
this.table = table;
}
public Table getTable() {
return table;
}
public void setTable(Table table) {
this.table = table;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class Table {
private String code;
public void setCode(String code) {
this.code = code;
}
@Override
public String toString() {
return "Table [code=" + code + "]";
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class Application {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
Room room = (Room) context.getBean("room");
if (room.getTable() != null) {
System.out.println(room.getTable().toString());
}
}
}
|
Và khai báo đối tượng Table và Room trong tập tin cấu hình của Spring
|
id="table" class="com.huongdanjava.springexample.Table">
name="code" value="123456" />
|
id="room" class="com.huongdanjava.springexample.Room">
OK, giờ mình sẽ đi lần lượt từng cách một và nói cho các bạn biết cụ thể về nó nhé!
byName
Như các bạn đã biết, mỗi bean trong khung chứa của Spring đều có 1 id của riêng nó. Dựa vào điều này, Spring quy định nếu id của đối tượng phụ thuộc (trong ví dụ của mình là đối tượng Table) giống với tên một biến nào đó trong đối tượng bị phụ thuộc (đối tượng Room) và khi khai báo đối tượng bị phụ thuộc, chúng ta khai báo thêm thuộc tính autowire=”byName” thì Spring sẽ tự động đưa đối tượng phụ thuộc vào đối tượng bị phụ thuộc qua phương thức setter của đối tượng bị phụ thuộc.
Trong ví dụ của mình, id của đối tượng Table đã hoàn toàn giống với tên biến table trong đối tượng Room, do đó chúng ta chỉ cần khai báo thêm cho bean room thuộc tínhautowire=”byName” thì Spring sẽ tự động đưa đối tượng Table vào đối tượng Room cho chúng ta.
Cấu hình của đối tượng Room sẽ sửa lại như sau
|
id="room" class="com.huongdanjava.springexample.Room" autowire="byName">
|
Khi chạy, chương trình sẽ cho ra kết quả như sau:
|
Mar 01, 2016 2:16:50 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1f17ae12: startup date [Tue Mar 01 14:16:50 ICT 2016]; root of context hierarchy
Mar 01, 2016 2:16:50 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring.xml]
Table [code=123456]
|
Cách này có bất lợi ở chỗ nếu sau này chúng ta thay đổi tên biến của đối tượng bị phụ thuộc, lại phải đi đổi lại tên id của đối tượng phụ thuộc trong khung chứa của Spring và ngược lại. Các bạn hình dung được chứ nhỉ?
byType
Cách này chúng ta chỉ áp dụng được với những project nhỏ khi mà mỗi đối tượng chỉ có một bean duy nhất trong khung chứa của Spring. Khi đó bằng cách thay đổi thuộc tính autowire=”byType” khi khai báo một bean, Spring sẽ tự động đưa đối tượng phụ thuộc vào đối tượng bị phụ thuộc cũng qua phương thức setter của đối tượng bị phụ thuộc.
|
id="room" class="com.huongdanjava.springexample.Room" autowire="byType">
|
Kết quả
|
Mar 01, 2016 2:32:12 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1f17ae12: startup date [Tue Mar 01 14:32:12 ICT 2016]; root of context hierarchy
Mar 01, 2016 2:32:12 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring.xml]
Table [code=123456]
|
Nếu các bạn cố tình khai báo thêm một bean khác của đối tượng phụ thuộc như sau
|
id="table" class="com.huongdanjava.springexample.Table">
name="code" value="123456" />
|
id="table1" class="com.huongdanjava.springexample.Table">
name="code" value="123456" />
id="room" class="com.huongdanjava.springexample.Room">
Thì khi chạy sẽ gặp lỗi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'room' defined in class path resource [spring.xml]: Unsatisfied dependency expressed through bean property 'table': : No qualifying bean of type [com.huongdanjava.springexample.Table] is defined: expected single matching bean but found 2: table,table1; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.huongdanjava.springexample.Table] is defined: expected single matching bean but found 2: table,table1
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'room' defined in class path resource [spring.xml]: Unsatisfied dependency expressed through bean property 'table': : No qualifying bean of type [com.huongdanjava.springexample.Table] is defined: expected single matching bean but found 2: table,table1; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.huongdanjava.springexample.Table] is defined: expected single matching bean but found 2: table,table1
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1307)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1199)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
at com.huongdanjava.springexample.Application.main(Application.java:9)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.huongdanjava.springexample.Table] is defined: expected single matching bean but found 2: table,table1
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1126)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1292)
... 13 more
|
constructor
Giống như thuộc tính autowire=”byType”, cách này chúng ta cũng chỉ áp dụng khi đối tượng của chúng ta chỉ có một bean duy nhất trong khung chứa của Spring. Khi đó, Spring sẽ tự động đưa đối tượng phụ thuộc vào đối tượng bị phụ thuộc qua constructor của đối tượng bị phụ thuộc.
Ví dụ, chúng ta thay đổi cấu hình của bean room như sau
|
id="room" class="com.huongdanjava.springexample.Room" autowire="constructor">
|
Kết quả
|
Mar 01, 2016 2:43:41 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1f17ae12: startup date [Tue Mar 01 14:43:41 ICT 2016]; root of context hierarchy
Mar 01, 2016 2:43:41 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring.xml]
Table [code=123456]
|
0 nhận xét:
Đăng nhận xét