IOC
IOC:控制反向 在使用Spring框架之后,对象的实例不再由调用者来创建,而是由Spring容器来创建,Spring容器会负责控制程序之间的关系,而不是由调用者的程序代码直接控制。
这样,控制权由应用代码转移到了Spring容器,控制权发生了反转,这就是控制反转。
DI
DI:依赖注入,可以为spring框架为创建的Bean对象,动态赋值, 依赖注入在spring创建对象的过程中,对象所依赖的属性通过配置注入对象中
从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,这相当于为调用者注入了它依赖的实例,这就是Spring的依赖注入。
通过实例看下控制反转和依赖注入:
public class UserDaorImp implements UserDao {
@Override
public void say() {
System.out.println("userDao say hello World !");
}
}
public class UserServiceImp implements UserService {
// 声明UserDao属性
private UserDao userDao;
// 添加UserDao属性的setter方法,用于实现依赖注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void say() {
this.userDao.say();
System.out.println("userService say hello World !");
}
}
创建applicationContext.xml
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 将指定类配置给Spring,让Spring创建其对象的实例 -->
<bean id="userDao" class="SSM.Dao.Imp.UserDaorImp" />
<!--添加一个id为userService的实例 -->
<bean id="userService" class="SSM.Service.Imp.UserServiceImp">
<!-- 将id为userDao的Bean实例注入到userService实例中 -->
<property name="userDao" ref="userDao" />
</bean>
</beans>
控制反转:
@Test
public void Testioc(){
//1.初始化spring容器,加载配置文件
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
//2.通过容器获取userDao实例
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
//3.调用实例中的say()方法
userDao.say();
}
依赖注入:
@Test
public void TestDI(){
//1.初始化spring容器,加载配置文件
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
//2.通过容器获取UserService实例
UserService userService =
(UserService) applicationContext.getBean("userService");
//3.调用实例中的say()方法
userService.say();
}
依赖注入方式
使用setter方法实现依赖注入(属性注入)
构造方法注入、工厂方式注入
注解注入
Setter注入
private UserDao userDao;
// 添加UserDao属性的setter方法,用于实现依赖注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
配置文件applicationContext.xml中,创建一个id为userService的Bean,该Bean用于实例化UserServiceImpl类的信息,并将userDao的实例注入到userService中。
<bean id="userService" class="com.itheima.ioc.UserServiceImpl">
<property name="userDao" ref="userDao" />
</bean>
<bean id="people" class="com.spring.test.People">
<property name="pet" ref="pet"></property>
</bean>
<bean id="pet" class="com.spring.test.Pet">
<property name="name" value="旺财"></property>
<property name="sex" value="男"></property>
<property name="age" value="3"></property>
</bean>
构造注入
构造方法注入就是通过bean的构造方法进行注入另个bean
<bean id="people" class="com.spring.test.People">
<constructor-arg name="name" value="wangdonghui"></constructor-arg>
<constructor-arg name="pet" ref="pet"></constructor-arg>
</bean>
<bean id="pet" class="com.spring.test.Pet">
<property name="name" value="旺财"></property>
<property name="sex" value="男"></property>
<property name="age" value="3"></property>
</bean>
<!--设置null-->
<property name="name">
<null></null>
</property>
<property name="gender" value=""></property>
<!--引用外部Bean
<property name="wife" ref="wife"></property>-->
<!--使用内部bean 依赖注入其他bean-->
<property name="wife">
<bean class="cn.tulingxueyuan.beans.Wife">
<property name="age" value="18"></property>
<property name="name" value="地理热吗"></property>
</bean>
</property>
<!--list 注入:
如果泛型是基本数据类型<value>
如果泛型是bean <bean>-->
<property name="hobbies">
<list>
<value>唱歌</value>
<value>跳舞</value>
</list>
</property>
<!--map 注入
如果value是基本数据类型<entry key="1" value="Java"></entry>
如果value是bean value-ref-->
<property name="course">
<map>
<entry key="1" value="Java"></entry>
<entry key="2" value="数据库"></entry>
</map>
</property>
<!--使用p命名空间简化基于setter属性注入XML配置
p:按Alt+Enter 自动加上命名空间
设置基本数据类型 或者p:wife-ref 引用外部bean
如果有集合类型 就不支持, 需要额外配置 <property>
-->
<bean class="cn.tulingxueyuan.beans.Wife" id="wife" p:age="18" p:name="迪丽热巴">
</bean>
<bean class="cn.tulingxueyuan.beans.Person" id="person2" p:wife-ref="wife2" >
<property name="hobbies">
<list>
<value>唱歌</value>
<value>跳舞</value>
</list>
</property>
</bean>
<!--使用c命名空间简化基于构造函数的XML-->
<bean class="cn.tulingxueyuan.beans.Wife" id="wife2" c:age="20" c:name="林青霞">
<!--<constructor-arg></constructor-arg>-->
</bean>
注解注入
@Autowired:自动注入的方式进行注入,默认根据类的名称来进行装配
@Resource(name="")没有name时和autowired一样但是他可以根据名称进行装配
@Repository("userDao")
public class UserDaoImpl implements UserDao{
public void save(){
System.out.println("userdao...save...");
}
}
@Service("userService")
public class UserServiceImpl implements UserService{
@Resource(name="userDao")
private UserDao userDao;
public void save() {
//调用userDao中的save方法
this.userDao.save();
System.out.println("userservice....save...");
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
主要有四种注解可以注册bean,每种注解可以任意使用,只是语义上有所差异:
@Component:可以用于注册所有bean
@Repository:主要用于注册dao层的bean
@Controller:主要用于注册控制层的bean
@Service:主要用于注册服务层的bean
在写DAO函数的时候,一般要写一个@Mapper,作用为
1:为了把mapper这个DAO交给Spring管理
2:为了不再写mapper映射文件
3:为了给mapper接口 自动根据一个添加@Mapper注解的接口生成一个实现类
@mapper注解
从mybatis3.4.0开始加入了@Mapper注解,目的就是为了不再写mapper映射文件