Sping配置文件-Bean的依赖注入
1.Bean的依赖注入分析
Spring框架的核心功能之一就是通过依赖注入的方式来管理Bean之间的依赖关系。
每个基于应用程序的 java 都有几个对象,由这些对象一起工作来呈现出终端用户所看到的工作的应用程序。当编写一个复杂的 Java 应用程序时,应用程序类应该尽可能独立于其他 Java 类来增加这些类重用的可能性,并且在做单元测试时,测试独立于其他类的独立性。依赖注入(或有时称为布线)
有助于把这些类粘合在一起,同时保持他们独立。
依赖注入(Dependency Injection):它是Spring框架核心IOC的具体实现。
在编写程序时,通过控制反转,把对象的创建权交给了Spring,但是代码中不可能出现没有依赖的情况。IOC解耦只是降低了他们的依赖关系,但是不会消除。例如:业务层仍会调用持久层的方法。
那这种业务层和持久层的依赖关系,在使用Spring之后,就让Spring来维护了。简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取了。我们只需要获取业务层的对象,从而最终操作Dao层的方法。
业务层调用Dao层
UserService要调UserDao,UserDao对象已经让Spring给我产生了
UserController.java(相当于web层)
package com.company.demo; import com.company.service.UserService; import com.company.service.impl.UserServiceImpl; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserController { public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService1 = (UserService) applicationContext.getBean("userService"); userService1.save(); } }
service层:
UserService.java(接口)
package com.company.service; public interface UserService { public void save(); }
UserServiceImpl.java
package com.company.service.impl; import com.company.dao.UserDao; import com.company.service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserServiceImpl implements UserService { public void save() { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = (UserDao) applicationContext.getBean("userDao"); userDao.save(); } }
dao层:
UserDao.java
package com.company.dao; public interface UserDao { public void save(); }
UserDaoImpl.java
package com.company.dao.impl; import com.company.dao.UserDao; public class UserDaoImpl implements UserDao { public UserDaoImpl() { System.out.println("UserDaoImpl创建..."); } public void init() { System.out.println("初始化方法...."); } public void destroy() { System.out.println("销毁方法...."); } public void save() { System.out.println("save running..."); } }
目前UserService实例和UserDao实例都存在于Spring实例中,当前的做法是在容器外部获得UserService实例和UserDao实例,然后在程序中进行结合。
因为UserService和UserDao都在Spring容器中,而最终程序直接使用的是UserService,所以可以在Spring容器中,将UserDao设置到UseService内部。即Service需要Dao的依赖注入。
2.怎么把将UserDao设置到UseService内部?
两种方式:
(1)set方法
这样不用通过容器获得Dao了,而是通过set方法将Dao注给了Service。
设置之后,在配置文件中要告诉Spring容器把Dao注给Service。
再去执行web层的代码UserController.java
set方法注入的简化方法:
P命名空间注入本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下:
首先,引入P命名空间
其次,需要修改注入方式
加属性,代替子标签
完整版的
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- <bean id="userDao" class="com.company.dao.impl.UserDaoImpl"></bean>--> <!-- <bean id="userDao" class="com.company.factory.StaticFactory" factory-method="getUserDao"></bean>--> <!-- <bean id="factory" class="com.company.factory.DynamicFactory"></bean>--> <!-- <bean id="UserDao" factory-bean="factory" factory-method="getUserDao"></bean>--> <bean id="userDao" class="com.company.dao.impl.UserDaoImpl"></bean> <!-- <bean id="userService" class="com.company.service.impl.UserServiceImpl">--> <!-- <property name="userDao" ref="userDao"></property>--> <!-- </bean>--> <bean id="userService" class="com.company.service.impl.UserServiceImpl" p:userDao-ref="userDao"></bean> </beans>
(2)构造方法(有参构造)
UserServiceImpl.java
package com.company.service.impl; import com.company.dao.UserDao; import com.company.service.UserService; public class UserServiceImpl implements UserService { private UserDao userDao; // public void setUserDao(UserDao userDao) { // this.userDao = userDao; // } public UserServiceImpl(UserDao userDao) { this.userDao = userDao; } public UserServiceImpl() { } public void save() { userDao.save(); } }
3.Bean的依赖注入的数据类型
上面的操作,都是注入的引用Bean,除了对象的引用可以注入,普通数据类型,集合等都可以在容器中进行注入。
以下都是用set方法注入
(1)普通数据类型注入
为什么不用ref,因为ref表示对象的引用,这里username,age都是普通的数据类型
UserDaoImpl.java
package com.company.dao.impl; import com.company.dao.UserDao; public class UserDaoImpl implements UserDao { private String username; private int age; public void setUsername(String username) { this.username = username; } public void setAge(int age) { this.age = age; } public void save() { System.out.println(username+"...."+age); System.out.println("save running..."); } }
运行UseCtroller
package com.company.demo; import com.company.service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserController { public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService1 = (UserService) applicationContext.getBean("userService"); userService1.save(); } }
(2)集合数据类型注入
UserDaoImpl.java
package com.company.dao.impl; import com.company.dao.UserDao; import com.company.domain.User; import java.util.List; import java.util.Map; import java.util.Properties; public class UserDaoImpl implements UserDao { private List<String> stringList; private Map<String, User> userMap; private Properties properties; public void setStringList(List<String> stringList) { this.stringList = stringList; } public void setUserMap(Map<String, User> userMap) { this.userMap = userMap; } public void setProperties(Properties properties) { this.properties = properties; } public void save() { System.out.println(stringList); System.out.println(userMap); System.out.println(properties); System.out.println("save running..."); } }
User.java
package com.company.domain; public class User { private String name; private String addr; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddr() { return addr; } public void setAddr(String addr) { this.addr = addr; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", addr='" + addr + '\'' + '}'; } }
applicationContext.xml
<bean id="userDao" class="com.company.dao.impl.UserDaoImpl"> <property name="stringList"> <list> <value>aaa</value> <value>bbb</value> <value>ccc</value> <value>ddd</value> </list> </property> <property name="userMap"> <map> <entry key="user1" value-ref="user1"></entry> <entry key="user2" value-ref="user2"></entry> </map> </property> <property name="properties"> <props> <prop key="p1">ppp1</prop> <prop key="p2">ppp2</prop> <prop key="p3">ppp3</prop> </props> </property> </bean> <bean id="user1" class="com.company.domain.User"> <property name="name" value="tom"></property> <property name="addr" value="beijing"></property> </bean> <bean id="user2" class="com.company.domain.User"> <property name="name" value="lucy"></property> <property name="addr" value="tianjin"></property> </bean> <bean id="userService" class="com.company.service.impl.UserServiceImpl"> <constructor-arg name="userDao" ref="userDao"></constructor-arg> </bean>
执行UserController