一:介紹
情景:我們在給程序分層的時候:web層、業務層、持久層,各個層之間會有依賴。比如說:業務層和持久層,業務層的代碼在調用持久層的時候,傳統方式:new 持久層類。
進而進行調用,這種方式會導致耦合性較高,在修改一層代碼的時候,另一層的也需要更改代碼。不利於維護。這種關系叫做“依賴”。
如何解決?
解決:
Spring給咱們提供依賴注入,也就是說當一個類的對象注入的時候,伴隨着他依賴的類也注入。
代碼:
1)傳統方式:
1 package jd.com.service; 2 3 import jd.com.dao.UserDaoImpl; 4 import org.junit.Test; 5 6 public class UserServiceImpl implements UserService { 7 @Test 8 @Override 9 public void save() { 10 System.out.println("業務層調用持久層。"); 11 //傳統方式 12 UserDaoImpl userDao=new UserDaoImpl(); 13 userDao.save(); 14 } 15 }
這種方式導致各個層之間耦合性較高。
2)set方式依賴注入(類):
set方式:被依賴的類需要設置成字段,並且提供set方法。
private UserDaoImpl userDao;
public void setUserDao(UserDaoImpl userDao) {
this.userDao = userDao;
}
被依賴的來:
1 package jd.com.dao; 2 3 public class UserDaoImpl implements UserService{ 4 @Override 5 public void save() { 6 System.out.println("持久層保存數據。"); 7 } 8 }
調用的類:
1 package jd.com.service; 2 3 import jd.com.dao.UserDaoImpl; 4 import org.junit.Test; 5 6 public class UserServiceImpl implements UserService { 7 //set方式 8 9 private UserDaoImpl userDao; 10 11 public void setUserDao(UserDaoImpl userDao) { 12 this.userDao = userDao; 13 } 14 15 public void save(){ 16 System.out.println("業務層調用持久層。"); 17 userDao.save(); 18 } 19 }
測試類:
1 package jd.com.service; 2 3 import org.junit.Test; 4 import org.springframework.context.ApplicationContext; 5 import org.springframework.context.support.ClassPathXmlApplicationContext; 6 7 public class Testdemo { 8 @Test 9 public void testdemo(){ 10 ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml"); 11 UserService userService= (UserService) ac.getBean("userserv"); 12 userService.save(); 13 14 } 15 }
配置文件配置:
1 <bean id="dao" class="jd.com.dao.UserDaoImpl" /> 2 <!--如果是類的數需要使用ref 值為被依賴的類的id名字--> 3 <bean id="userserv" class= "jd.com.service.UserServiceImpl" > 4 <property name="userDao" ref="dao" /> 5 </bean>
3)set方法(設置字段):
字段注入也類似上面但是這種方式配置文件是不一樣的。
配置文件:
1 <bean id="userserv" class= "jd.com.service.UserServiceImpl" > 2 <property name="userDao" ref="dao" /> 3 <!--name是屬性key value是屬性value--> 4 <property name="oop" value="java"/> 5 </bean>
代碼:需要設置set方法
1 public String oop; 2 3 public void setOop(String oop) { 4 this.oop = oop; 5 }
1 @Test 2 public void test(){ 3 ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); 4 UserServiceImpl userService= (UserServiceImpl) ac.getBean("userserv"); 5 System.out.println(userService.oop); 6 }
4)構造方法依賴注入:
依賴類:在構造方法中進行屬性設置.
1 package jd.com.service; 2 3 import jd.com.dao.UserDaoImpl; 4 5 6 public class UserServiceImpl implements UserService { 7 8 9 public String ko; 10 public String ok; 11 private UserDaoImpl userDao; 12 13 14 public UserServiceImpl (UserDaoImpl userDao ,String ko ,String ok){ 15 this.userDao=userDao; 16 this.ko=ko; 17 this.ok=ok; 18 } 19 20 21 22 public void save(){ 23 System.out.println("業務層調用持久層。"); 24 userDao.save(); 25 } 26 }
測試代碼:
1 @Test 2 public void test2(){ 3 ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); 4 UserServiceImpl us= (UserServiceImpl) ac.getBean("userserv"); 5 us.save(); 6 System.out.println(us.ok); 7 System.out.println(us.ko); 8 } 9 }
配置文件配置:需要注意標簽是:1、constructor-arg 2、index和name不能混合使用。3、屬性是其他類的時候需要注意使用ref=“類的配置文件id”
1 <bean id="userserv" class="jd.com.service.UserServiceImpl"> 2 <constructor-arg name="userDao" ref="dao" /> 3 <constructor-arg name="ko" value="python" /> 4 <constructor-arg name="ok" value="java" /> 5 </bean> 6 <bean id="dao" class="jd.com.dao.UserDaoImpl" />
4)其他方式注入:Array,list、set、map、properites屬性文件注入(不常用SSH整合的時候會用到)
實現類:
1 package jd.com.service; 2 3 import jd.com.dao.UserDaoImpl; 4 5 6 public class UserServiceImpl implements UserService { 7 8 9 public String ko; 10 public String ok; 11 private UserDaoImpl userDao; 12 13 14 public UserServiceImpl (UserDaoImpl userDao ,String ko ,String ok){ 15 this.userDao=userDao; 16 this.ko=ko; 17 this.ok=ok; 18 } 19 20 21 22 public void save(){ 23 System.out.println("業務層調用持久層。"); 24 userDao.save(); 25 } 26 }
測試類:
1 package jd.com.other; 2 3 import org.junit.Test; 4 import org.springframework.context.ApplicationContext; 5 import org.springframework.context.support.ClassPathXmlApplicationContext; 6 7 import java.util.Arrays; 8 9 public class TestDemo { 10 @Test 11 public void testDemo(){ 12 ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); 13 InOtherImpl inOther= (InOtherImpl) ac.getBean("in"); 14 System.out.println(Arrays.toString(inOther.testar)); 15 } 16 @Test 17 public void testDemo2(){ 18 ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); 19 InOtherImpl inOther= (InOtherImpl) ac.getBean("in"); 20 System.out.println(inOther.list); 21 } 22 @Test 23 public void testDemo3(){ 24 ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); 25 InOtherImpl inOther= (InOtherImpl) ac.getBean("in"); 26 System.out.println(inOther.map); 27 } 28 @Test 29 public void testDemo4(){ 30 ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); 31 InOtherImpl inOther= (InOtherImpl) ac.getBean("in"); 32 System.out.println(inOther.pro); 33 } 34 }
配置文件:
1 <bean id="in" class="jd.com.other.InOtherImpl"> 2 <property name="testar"> 3 <list> 4 <value>io</value> 5 <value>oop</value> 6 <value>ok</value> 7 </list> 8 </property> 9 <property name="list" > 10 <list> 11 <value>java</value> 12 <value>python</value> 13 </list> 14 15 </property> 16 <property name="map"> 17 <map> 18 <entry key="oop" value="java" /> 19 </map> 20 </property> 21 <property name="pro"> 22 <props> 23 <prop key="url" >http://172.17.33.21:3358</prop> 24 <prop key="user" >root</prop> 25 <prop key="password" >123</prop> 26 </props> 27 </property> 28 </bean>
需要注意的是:
如果寫引用話 一般在value-ref的字段。