目录
依赖注入概念
上面的缺点也很明显,是同时获取service和dao层的到时我们只想要service层,所以此时,需要依赖注入,把dao注入到service服务层
依赖注入(DependencyInjection):它是Spring框架核心IOC的具体实现。
在编写程序时,通过控制反转,把对象的创建交给了Spring,但是代码中不可能出现没有依赖的情况。 IOC解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。
那这种业务层(Service)和持久层(Dao)的依赖关系,在使用Spring之后,就让Spring来维护了。简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。
将UserDao注入到UserService内部的方式
构造方法和set方法
法1:set方法
在UserServiceImpl下创建userDao
1 |
import com.Dao.UserDao; import com.Service.UserService; public class UserServiceImpl implements UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void save() { userDao.save(); } } |
在applicationContext.xml文件中配置
1 |
<bean id="userDao" class="com.Dao.impl.UserDaoImpl"></bean> <bean id="userService" class="com.Service.Impl.UserServiceImpl"> <property name="userDao" ref="userDao"></property> </bean> |
然后之前创建的UserController就可以启动了
如果直接new UserServiceImpl对象会报空指针异常的错,
因为useDao是不是通过spring容器来获取的,自然就是null值了
set注入方法改进
P命名空间注入本质也是set方法注入,但比起上述的set方法更加方便,首先需要引入p命名空间:
1 |
xmlns:p="http://www.springframework.org/schema/p" |
修改注入方式
1 |
<bean id="userService" class="com.Service.Impl.UserServiceImpl" p:userDao-ref="userDao"> |
是一个对象就用-ref,普通属性就不用
userController运行之后
有参构造注入方法
在applicationContext.xml文件中
1 |
<bean id="userService" class="com.Service.Impl.UserServiceImpl"> <!-- name后的userDao表示构造内部的参数名,ref表示引用容器bean的id--> <constructor-arg name="userDao" ref="userDao"></constructor-arg> </bean> |
userServiceImpl下
运行结果:
Bean的依赖注入的数据类型
上面的操作,都是注入引用Bean,除了对象的引用可以注入,普通数据类型,集合都可以在容器中进行注入。
注入数据的三种数据类型
- 普通数据类型
- 引用数据类型
- 集合数据类型
普通数据注入,如在UserDao层注入两个普通数据类型(采用set方式注入)
1 |
public class UserDaoImpl implements UserDao { private String name; private int age; public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void save(){ System.out.println("姓名:"+name+"年龄:"+age); System.out.println("run save..."); } } |
在applicationContext.xml文件中,在配置dao中设置参数
1 |
<bean id="userDao" class="com.Dao.impl.UserDaoImpl"> <property name="name" value="李四"/> <property name="age" value="20" /> </bean> |
在Usercontroller下
1 |
public class UserController { public static void main(String[] args) { ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) app.getBean("userService"); userService.save(); } } |
运行结果
集合的数据类型注入
在UserDaoImpl下
采用set注入方式,设置集合,提供对应得set方法
1 |
package com.Dao.impl; import com.Dao.UserDao; import com.pojo.User; import java.util.List; import java.util.Map; import java.util.Properties; public class UserDaoImpl implements UserDao { private List<String> strList; private Map<String, User> userMap; private Properties properties; public void setStrList(List<String> strList) { this.strList = strList; } public void setUserMap(Map<String, User> userMap) { this.userMap = userMap; } public void setProperties(Properties properties) { this.properties = properties; } public void play(){ System.out.println("play and play..."); } public void save(){ System.out.println("List集合-》"+strList); System.out.println("Map集合-》"+userMap); System.out.println("properties集合-》"+properties); System.out.println("run save..."); } } |
在applicationContext.xml下配置注入值
1 |
<?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.Dao.impl.UserDaoImpl">--> <!-- <property name="name" value="李四"/>--> <!-- <property name="age" value="20" />--> <!--</bean>--> <bean id="userDao" class="com.Dao.impl.UserDaoImpl"> <!--给list集合注入值 --> <property name="strList" > <list> <value>慧慧</value> <value>孔超</value> <value>宝</value> </list> </property> <property name="userMap"> <map> <!--key表示map里的key,value-ref是对象的引用,引用id为user1和user2 --> <entry key="宝1" value-ref="user1"></entry> <entry key="宝2" value-ref="user2"></entry> </map> </property> <!-- 给properties注入的值 --> <property name="properties"> <props> <prop key="p1">宝1</prop> <prop key="p2">宝2</prop> </props> </property> </bean> <!-- 这是给map对象的user设置的值的--> <bean id="user1" class="com.pojo.User"> <property name="name" value="慧慧"/> <property name="address" value="赣州"/> </bean> <bean id="user2" class="com.pojo.User"> <property name="name" value="孔超"/> <property name="address" value="赣州"/> </bean> <bean id="userService" class="com.Service.Impl.UserServiceImpl"> <!-- name后的userDao表示构造内部的参数名,ref表示引用容器bean的id--> <constructor-arg name="userDao" ref="userDao"></constructor-arg> </bean> </beans> |
在UserController测试下
1 |
import com.Service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserController { public static void main(String[] args) { ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) app.getBean("userService"); userService.save(); } } |
运行结果:
引入其他配置文件(分模块开发)
实际开发中,Spring的配置内容非常的多,这就导致Spring配置很繁琐且体积很大,所以可以将部分配置拆解到其他配置文件中,而且主配置文件通过import标签进行加载
语法格式:
1 |
<import resource="xxxx.xml"/> |
Spring的重点配置
<bean>标签
- id属性:在容器中Bean实例的唯一标识,不允许重复
- class属性:要实例化的Bean的全限定名
- scope属性:bean的作用范围,常用是Singleton(默认)和prototype
<property>标签:属性注入
- name属性:属性名称
- value属性:注入的普通属性值
- ref属性:注入的对象引用值
<list>标签
<map>标签
<constructor-arg>标签
<import>标签:导入其他的Spring的分文件