java之Spring裝配Bean(手動裝配、自動裝配、註解裝配)
在上一篇控制反轉中我們看到了依靠一個Bean文件來實現對代碼的控制,可謂十分便捷,再也不用去實例化對象了,2333~~~
1.手動裝配
1 <bean id="todo" class="com.eco.daoimp.Usertodo1"></bean> 2 3 <!--定義Userservice類內部接口的引用(userdao)指向具體的實現類對象(Usertodo1) --> 4 <bean id="userservice" class="com.eco.service.Userservice"> 5 <property name="userdao" ref="todo"></property>
6 </bean>
這裏我們是手動裝配Bean,指定Userservice類下的成員變量userdao是Usertodo1的實例化對象。
2.自動裝配
1 <bean id="userdao2" class="com.eco.daoimp.Usertodo2" />
2 <bean id="userdao" class="com.eco.daoimp.Usertodo1" />
3 <bean id="userservice" class="com.eco.service.Userservice" auto-wire="byName"/>
看這個自動裝配類型:
byName:為Userservice類下的成員變量userdao自動裝配id/name屬性為userdao的bean,就是第二個bean,如果找不到名
為userdao的bean,就會報錯!!!
byType:為Userservice類下的成員變量userdao自動裝配與之類型相同(UserDao)的bean,因為Usertodo1和Usertodo2
都是UserDao的實現了類,所以都會符合要求,那麽程序就在糾結:到底裝配id是userdao的bean還是裝配id為
userdao2的bean呢,遲遲下不了決定,只好報錯!!!所以慎用~~
除此之外還有一個在beans標簽定義的default-auto-wire="byName",相當於一個全局聲明,告訴所有的bean標簽采用我說
的聲明方式進行裝配。
3.註解裝配
annotation註解,註解就是采用一個@加上字段進行聲明,就像我們常見的@Test、@Override等等
采用註解進行裝配之前,bean.xml文件要較之前有個改變:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context-3.1.xsd"> 9 10 <context:component-scan base-package="com.eco"></context:component-scan>
11 </beans>
紅字是較之前手動裝配/自動裝配新增的聲明字段,然後內部只有一個標簽,這個標簽告訴容器要解析哪個包下的bean。
1 @Service 2 public class Userservice { 3 // 定義接口的引用 4 private UserDao userdao; 5 6 // 定義setter方法,設置接口的引用指向哪個實現類的對象 7 @Autowired 8 public void setUserdao(UserDao userdao) { 9 this.userdao = userdao; 10 } 11 12 public void useradd(User newuser) { 13 // 此時的userdao經過spring依賴註入之後已經實現指向特定的接口實現類對象 14 // 那麽調用接口的方法,實際上是調用了特定實現類的方法的 15 userdao.adduser(newuser); 16 } 17 }
1 @Repository 2 public class Usertodo1 implements UserDao { 3 // 接口實現類為方法添加方法體 4 public void adduser(User user) { 5 // 利用Hibernate的工廠類獲得Session對象和事務對象Transaction 6 Session session = HibernateSessionFactory.getSession(); 7 Transaction transaction = session.beginTransaction(); 8 // 數據庫添加用戶操作 9 session.save(user); 10 // 提交事務 11 transaction.commit(); 12 // 關閉session對象 13 session.close(); 14 System.out.println("todo1 create the user"); 15 } 16 }
紅字標註的三個註解意思就是:為@Service聲明的Userservice類,內部的@Autowired聲明的userdao變量,註入了
@Repository聲明的Usertodo1實現類。
依賴註入有①接口註入②setter註入③構造方法註入,很明顯上面的例子是setter註入,
接口註入就將註解寫在定義的成員變量上;
setter註入就將註解寫在setter方法上;
構造方法註入就將註解寫在構造方法上(很明顯上面沒有定義構造方法)。
調用的時候方法還是和之前一樣:
1 public class Test1 { 2 @Test 3 public void add() { 4 // Spring讀取beans。xml文件 5 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 6 // 解析id為userservice的bean標簽,內部實現UserDao userdao = new Usertodo1() 7 Userservice service = (Userservice) ctx.getBean("userservice"); 8 User newuser = new User("桔子桑", 31); 9 // 此時調用的useradd()方法,就是接口實現類Usertodo1的useradd()方法 10 service.useradd(newuser); 11 } 12 }
只是這個bean的名稱,默認是采用@Service聲明的類的名稱首字母小寫,其余不變作為bean的id/name;
我們也是可以自定義這個bean名稱的,@Service("eco"),像這樣在括號裏就可以自定義名稱了。
java之Spring裝配Bean(手動裝配、自動裝配、註解裝配)