Trong Java chúng ta có kế thừa đối tượng sử dụng từ khóa abstract, Spring cũng hỗ trợ chúng ta làm điều tương tự trong bản thân nó. Bài viết này mình sẽ trình bày cho các bạn biết cách để sử dụng kế thừa bean trong Spring như thế nào?
OK, đầu tiên chúng ta cần phải có một Maven project để làm việc. Mình đã tạo Maven project như sau:
Trong đó, Spring framework dependency như sau:
1 2 3 4 5 |
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>6.0.2</version> </dependency> |
Clazz class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.huongdanjava.springinheritance; public class Clazz { private String name; private String schoolName; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSchoolName() { return schoolName; } public void setSchoolName(String schoolName) { this.schoolName = schoolName; } } |
Application class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.huongdanjava.springinheritance; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Application { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Clazz clazzA = (Clazz) context.getBean("clazzA"); System.out.println("\n" + clazzA.getSchoolName()); } } |
Để có thể sử dụng kế thừa, ít nhất các bean được khai báo trong khung chứa của Spring phải có một đặc điểm chung nào đó. Vì thế mình trong class Clazz ở trên, mình đã khai báo một field làm đặc điểm chung cho tất cả các bean đó là tên trường, schoolName.
Trong Spring container, mình khai báo khởi đầu như sau:
1 2 3 4 5 6 7 8 9 10 11 |
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="clazzA" class="com.huongdanjava.springinheritance.Clazz"> </bean> <bean id="clazzB" class="com.huongdanjava.springinheritance.Clazz"> </bean> </beans> |
OK, bây giờ mình sẽ khai báo thêm một bean chung cho tất cả các đối tượng Clazz có cùng tên trường “Tam Quan Nam” như sau.
1 2 3 |
<bean id="generalClazz" class="com.huongdanjava.springinheritance.Clazz"> <property name="schoolName" value="Tam Quan Nam" /> </bean> |
Để bean clazzA và bean clazzB có thể sử dụng bean chung trên chúng ta cần khai báo thêm thuộc tính parent với giá trị là id của bean chung, trong phần khai báo của bean clazzA và bean clazzB, như sau:
1 2 3 4 5 |
<bean id="clazzA" class="com.huongdanjava.springinheritance.Clazz" parent="generalClazz"> </bean> <bean id="clazzB" class="com.huongdanjava.springinheritance.Clazz" parent="generalClazz"> </bean> |
Bây giờ nếu chạy chương trình, các bạn sẽ thấy kết quả như sau:
Các bạn có thể thấy, mặc dù chúng ta không khai báo field schoolName cho bean clazzA nhưng bean clazzA vẫn có tên trường vì nó được kế thừa từ bean generalClazz.
Cũng cần nói thêm rằng trong trường hợp này bean generalClazz của chúng ta cũng được khởi tạo trong khung chứa của Spring và chúng ta có thể lấy ra nó:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.huongdanjava.springinheritance; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Application { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Clazz generalClazz = (Clazz) context.getBean("generalClazz"); System.out.println("\n" + generalClazz.getSchoolName()); } } |
Kết quả:
Nếu các bạn muốn nó chỉ là một abstract như định nghĩa trong Java, nghĩa là không thể khởi tạo được trong khung chứa của Spring, chúng ta có thể khai báo thêm thuộc tính abstract=”true”:
1 2 3 |
<bean id="generalClazz" class="com.huongdanjava.springinheritance.Clazz" abstract="true"> <property name="schoolName" value="Tam Quan Nam" /> </bean |
Trong trường hợp này, nếu các bạn chạy lại đoạn code trên, sẽ gặp ngay lỗi sau:
1 2 3 4 5 6 |
Exception in thread "main" org.springframework.beans.factory.BeanIsAbstractException: Error creating bean with name 'generalClazz': Bean definition is abstract at org.springframework.beans.factory.support.AbstractBeanFactory.checkMergedBeanDefinition(AbstractBeanFactory.java:1451) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1130) at com.huongdanjava.springinheritance.Application.main(Application.java:11) |
Minh Anh
nếu mình không nhầm thì code này của bạn in kết quả ra null đó chứ có in được ra Tam Quan Nam đâu. chắc chắn đấy
Khanh Nguyen
Bạn ra null hả?
trongnb
a cho e hỏi trong trường hợp này sao lại là kế thừa ạ ,vì đây bản chất là 2 đối tượng của cùng 1 class ,cái này kiểu như chỉ share chung dữ liệu thôi chứ a ,nó giống biến static . K biết e suy nghĩ vậy có phải không
giặc núi
có abstract thì có interface ko anh!!
Khanh Nguyễn
Kế thừa chỉ có abstract thôi nha em.