一.IOC,即控制反转
全名:Inversion of Control
目的:解耦合
含义:由对象自身创建自己的关联或者依赖 对象,改变为由外部容器将关联或依赖对象注入。
二.别名:依赖注入(DI)
通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。
DI的注入方式:
1.setter注入
bean包
package com.it.user.bean;
public class UserInfo {
private String user_id;
private String user_name;
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
@Override
public String toString() {
return "UserInfo [user_id=" + user_id + ", user_name=" + user_name + "]";
}
public UserInfo(String user_id, String user_name) {
super();
this.user_id = user_id;
this.user_name = user_name;
}
public UserInfo() {
super();
// TODO Auto-generated constructor stub
}
}
services包
package com.it.user.services;
import com.it.user.bean.UserInfo;
import java.util.List;
public interface IUserInfoService {
void addUser(UserInfo userInfo);
void delUser(UserInfo userInfo);
void updateUser(UserInfo userInfo);
List<UserInfo> queryAll(UserInfo userInfo);
}
package com.it.user.services;
import com.it.user.bean.UserInfo;
import com.it.user.dao.IUserInfoDAO;
import java.util.List;
public class UserInfoServicesImpl implements IUserInfoService {
private IUserInfoDAO userInfoDAO;
public void setUserInfoDAO(IUserInfoDAO userInfoDAO) {
this.userInfoDAO = userInfoDAO;
}
@Override
public void addUser(UserInfo userInfo) {
userInfoDAO.addUser(userInfo);
System.out.println("----UserInfoServiceImpl-------");
}
@Override
public void delUser(UserInfo userInfo) {
userInfoDAO.delUser(userInfo);
System.out.println("----UserInfoServiceImpl-------");
}
@Override
public void updateUser(UserInfo userInfo) {
userInfoDAO.updateUser(userInfo);
System.out.println("----UserInfoServiceImpl-------");
}
@Override
public List<UserInfo> queryAll(UserInfo userInfo) {
userInfoDAO.queryAll(userInfo);
System.out.println("----UserInfoServiceImpl-------");
return null;
}
}
dao包
package com.it.user.dao;
import com.it.user.bean.UserInfo;
import java.util.List;
public interface IUserInfoDAO {
void addUser(UserInfo userInfo);
void delUser(UserInfo userInfo);
void updateUser(UserInfo userInfo);
List<UserInfo> queryAll(UserInfo userInfo);
}
package com.it.user.dao;
import com.it.user.bean.UserInfo;
import java.util.List;
public class UserInfoDAO implements IUserInfoDAO {
// public UserInfoDAO(){
// System.out.println("-------created-----------");
// }
@Override
public void addUser(UserInfo userInfo) {
System.out.println("-----add--UserInfoDAO-------");
}
@Override
public void delUser(UserInfo userInfo) {
System.out.println("-----del--UserInfoDAO-------");
}
@Override
public void updateUser(UserInfo userInfo) {
System.out.println("-----update--UserInfoDAO-------");
}
@Override
public List<UserInfo> queryAll(UserInfo userInfo) {
System.out.println("-----queryAll--UserInfoDAO-------");
return null;
}
public void init(){
System.out.println("---init-----------");
}
public void destroy(){
System.out.println("-------destroy()--------");
}
}
controller包
package com.it.user.controller;
import com.it.user.bean.UserInfo;
import com.it.user.services.IUserInfoService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserInfoController {
//私有属性
private UserInfo userInfo;
private IUserInfoService userInfoServiceImpl;
//共有set方法
public void setUserInfoServiceImpl(IUserInfoService userInfoServiceImpl) {
this.userInfoServiceImpl = userInfoServiceImpl;
}
public void setUserInfo(UserInfo userInfo) {
this.userInfo = userInfo;
}
//增删改查
public void addUser(){
System.out.println("--------addcontroller---------");
this.setUserInfo(new UserInfo());
this.userInfoServiceImpl.addUser(this.userInfo);
}
public void delUser(){
System.out.println("--------delcontroller---------");
this.setUserInfo(new UserInfo());
this.userInfoServiceImpl.delUser(this.userInfo);
}
public void updateUser(){
System.out.println("--------updatecontroller---------");
this.setUserInfo(new UserInfo());
this.userInfoServiceImpl.updateUser(this.userInfo);
}
public void queryAll(){
System.out.println("--------queryAllcontroller---------");
this.setUserInfo(new UserInfo());
this.userInfoServiceImpl.queryAll(this.userInfo);
}
public static void main(String[] args) {
//获取配置的xml文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
//通过反射机制,配置文件的id获取当前类的对象 getBean
UserInfoController userInfoController = applicationContext.getBean("userInfoController",UserInfoController.class);
userInfoController.addUser();
userInfoController.delUser();
userInfoController.updateUser();
userInfoController.queryAll();
}
}
在这里插入代码片
2.构造方法注入
bean包
package com.it.bean;
public class Employee {
@Override
public String toString() {
System.out.println("------Employee--------");
return "";
}
}
controller包
package com.it.controller;
import com.it.bean.Employee;
import com.it.bean.Item;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DemoController {
private Employee employee;
private Item item;
int x;
int y;
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public DemoController() {
}
public DemoController(int x, int y) {
this.x = x;
this.y = y;
}
public DemoController(Employee employee, Item item, int x) {
this.employee = employee;
this.item = item;
this.x = x;
}
private String name;
public DemoController(String name){
this.name = name;
}
public DemoController(int x, int y, String name) {
this.x = x;
this.y = y;
this.name = name;
}
public void testIOC(){
System.out.println("name---->"+name);
System.out.println("x-->"+x);
System.out.println("y-->"+y);
System.out.println("item--->"+item);
System.out.println("employee-->"+employee);
}
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext2.xml");
DemoController demoController = applicationContext.getBean("demoController",DemoController.class);
demoController.testIOC();
}
}
3.集合类型的装配
如下展示:
package com.it.controller;
import com.it.services.AccountService;
import com.it.services.AccountServiceImpl;
import com.it.services.ClientServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class DemoController2 {
private String[]array;
private Properties myPro;
private List<String> stringList;
private Set<String> stringSet;
private Map<String,Integer> maps;
public void setArray(String[] array) {
this.array = array;
}
public void setMyPro(Properties myPro) {
this.myPro = myPro;
}
public void setMaps(Map<String, Integer> maps) {
this.maps = maps;
}
public void setStringSet(Set<String> stringSet) {
this.stringSet = stringSet;
}
public void setStringList(List<String> stringList) {
this.stringList = stringList;
}
public void testColl(){
System.out.println("-----list---------");
for (String str:stringList
) {
System.out.println(str);
}
System.out.println("--------array-----------");
for (String str: array
) {
System.out.println(str);
}
System.out.println("--------properties-----------");
System.out.println(myPro);
System.out.println("--------set-----------");
for (String str: stringSet
) {
System.out.println(str);
}
System.out.println("-------map-----------");
for (String str: maps.keySet()
) {
System.out.println("key-->"+str+",value-->"+maps.get(str));
}
}
public static void main(String[] args) {
// ApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[]{"applicationContext3.xml"});
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext3.xml");
DemoController2 demoController = applicationContext.getBean("demoController2",DemoController2.class);
demoController.testColl();
}
}
3.4 空配置
设置value 为空或为 null
5 延迟初始化
中属性为lazy-init 为 true
6 自动装配
三.Spring提供了三种主要方式来配置IOC容器中的bean
1.基于xml文件配置
(1).setter注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
xmlns:p="http://www.springframework.org/schema/p"
>
<!-- set注入方式 -->
<!-- dao实现类-->
<bean id="userInfoDAO" class="com.it.user.dao.UserInfoDAO" scope="prototype" init-method="init" destroy-method="destroy">
</bean>
<!--services实现类-->
<bean id="userInfoServiceImpl" class="com.it.user.services.UserInfoServicesImpl" p:userInfoDAO-ref="userInfoDAO">
<!-- <property name="userInfoDAO" ref="userInfoDAO"></property>-->
</bean>
<!--controller -->
<bean id="userInfoController" class="com.it.user.controller.UserInfoController">
<property name="userInfoServiceImpl" ref="userInfoServiceImpl"></property>
</bean>
</beans>
(2).构造方法注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="item" class="com.it.bean.Item"></bean>
<bean id="employee" class="com.it.bean.Employee"></bean>
<!-- spring ioc注入方式-->
<bean id="demoController" class="com.it.controller.DemoController" >
<!-- set注入 -->
<!--<property name="name" value="张三"></property>
<property name="name"><value>李四</value></property>
<property name="x" value="1"></property>
<property name="y" value="2"></property>-->
<!-- 构造器注入 -->
<!-- <constructor-arg name="name" value="哈哈"></constructor-arg>-->
<!-- <constructor-arg name="name"><value>1111</value></constructor-arg>-->
<!-- <constructor-arg index="0"><value>哈哈2</value></constructor-arg>-->
<!-- <constructor-arg type="java.lang.String"><value>(#^.^#)</value></constructor-arg>-->
<!-- <constructor-arg name="name" value="大西安" ></constructor-arg>-->
<!-- <constructor-arg name="x" value="110" ></constructor-arg>-->
<!-- <constructor-arg name="y" value="120" ></constructor-arg>-->
<!-- <constructor-arg type="int" value="1"></constructor-arg>
<constructor-arg type="int" value="2"></constructor-arg>-->
<!-- <constructor-arg name="item" ref="item"></constructor-arg>-->
<!-- <constructor-arg name="employee" ref="employee"></constructor-arg>-->
<!-- <constructor-arg name="x" value="1"></constructor-arg>-->
</bean>
</beans>
(3).基于集合
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="demoController2" class="com.it.controller.DemoController2">
<!--list -->
<property name="stringList">
<list>
<value>a</value>
<value>a1</value>
<value>a2</value>
<value>a3</value>
<value>a</value>
<value>1</value>
</list>
</property>
<!--array-->
<property name="array">
<array>
<value>a</value>
<value>a1</value>
<value>a2</value>
<value>a3</value>
<value>a</value>
<value>1</value>
</array>
</property>
<!--properties只能储存一个-->
<property name="myPro">
<props>
<prop key="num">a</prop>
</props>
</property>
<property name="stringSet">
<set>
<value>a</value>
<value>a1</value>
<value>a2</value>
<value>a3</value>
<value>a</value>
<value>12</value>
<value>31</value>
<value>1</value>
<value>1</value>
<value>1</value>
</set>
</property>
<!-- <property name="maps">
<map>
<entry key="a" value="1"></entry>
<entry key="b" value="2"></entry>
<entry key="c" value="3"></entry>
<entry key="d" value="4"></entry>
</map>
</property>-->
<property name="maps">
<map>
<entry key="aa">
<value>1</value>
</entry>
<entry key="aa2">
<value>11</value>
</entry>
<entry key="aa31">
<value>311</value>
</entry>
<entry key="aa31">
<value>31</value>
</entry>
</map>
</property>
</bean>
<!--静态工厂-->
<!-- <bean id="clientService" class="com.it.controller.ClientService" factory-method="createInstance"></bean>-->
<!--实例工厂-->
<bean id="serviceLocator" class="com.it.controller.DefaultServiceLocator"></bean>
<bean id="clientService2" factory-method="createClientServiceInstance" factory-bean="serviceLocator"></bean>
<bean id="accountService2" factory-method="createAccountServiceInstance" factory-bean="serviceLocator" ></bean>
</beans>
2.基于注解配置
Spring提供的注解有:
(1).@component:(组件)实现Bean组件的定义
@Repository:用于标注DAO类
@Service:用于标注业务类
@Controller:用于标注控制器类
(2).属性注入的注解
a.普通属性:
@value:设置普通属性的值
b.对象类型的属性:
@Autowired:按类型注入,括号里面required=false。一般与@Qualifier一起使用
@Resource:按名称注入
- @Resource后面没有任何内容,默认通过name属性去匹配bean,找不到再按type去匹配
- 指定了name或者type则根据指定的类型去匹配bean
- 指定了name和type则根据指定的name和type去匹配bean,任何一个不匹配都将报错
两者的区别:
(1)、@Autowired默认按照byType方式进行bean匹配,@Resource默认按照byName方式进行bean匹配
(2)、@Autowired是Spring的注解,@Resource是J2EE(jdk1.6)的注解,Spring属于第三方的,J2EE是Java自己的东西,因此,建议使用@Resource注解,以减少代码和Spring之间的耦合
开启注解:
《1》引用配置文件:
<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">
《2》.创建相关的类和包
dao包
package com.it.ioc1.item.dao;
public interface IOrderDAO {
void addOrder();
}
package com.it.ioc1.item.dao;
import org.springframework.stereotype.Repository;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
//<bean id="orderDAOImpl" class="com.it.ioc1.item.dao.OrderDAOImpl">
//@Component
// <bean id="userInfoDAO" class="com.it.dao.UserInfoDAO" scope="prototype" init-method="init" destroy-method="destroy">
@Repository("orderDAOImpl")
public class OrderDAOImpl implements IOrderDAO {
@PostConstruct
public void init(){
System.out.println("-----OrderDAOImpl init-------------");
}
@Override
public void addOrder()
{
System.out.println("---OrderDAOImpl add--------------");
}
@PreDestroy
public void destroy(){
System.out.println("-----OrderDAOImpl destroy---------");
}
}
services包
package com.it.ioc1.item.services;
public interface IOrderService {
void addOrder();
}
package com.it.ioc1.item.services;
import com.it.ioc1.item.dao.IOrderDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
//<bean id="orderServiceImpl" class="com.it.ioc1.item.services.OrderServiceImpl">
//@Component("orderServiceImpl")
@Service("orderServiceImpl")
@Scope
//@Scope("prototype")
public class OrderServiceImpl implements IOrderService {
/**
* <bean id="orderServiceImpl" class="com.it.ioc1.item.services.OrderServiceImpl">
* <property name="orderDAOImpl" ref="orderDAOImpl"></property>
* </bean>
*/
// @Autowired //按照类型去匹配
// @Resource //按照名称去匹配
// @Resource(name="orderDAOImpl")
@Autowired
// @Qualifier("orderDAOImpl")
IOrderDAO orderDAOImpl;
@Value("的莉莉")
private String name;
/* @Value("得力")
public void setName(String name) {
this.name = name;
}
*/
public String getName() {
return name;
}
@Override
public void addOrder() {
orderDAOImpl.addOrder();
System.out.println("-----OrderServiceImpl-----------");
}
}
开启IOC注解
<!-- spring下的注解;多个包用”;”分开-->
<context:component-scan base-package="com.it.ioc1.item.services;com.it.ioc1.item.dao">
</context:component-scan>
测试类
package com.it.ioc1.item.testIOC;
import com.it.ioc1.item.services.IOrderService;
import com.it.ioc1.item.services.OrderServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringIOCTest {
@Test
public void addOrder(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
IOrderService service = context.getBean("orderServiceImpl", OrderServiceImpl.class);
service.addOrder();
// System.out.println(((OrderServiceImpl) service).getName());
// ((ClassPathXmlApplicationContext) context).close();
// IOrderService service1 = context.getBean("orderServiceImpl", OrderServiceImpl.class);
// IOrderService service2 = context.getBean("orderServiceImpl", OrderServiceImpl.class);
//
// System.out.println(service1==service2);
// System.out.println(service1.hashCode());
// System.out.println(service2.hashCode());
}
}
3.基于注解+java代码显示配置
四.使用IOC的好处
1.资源集中管理,实现资源的可配置和易管理
2.降低了资源的依赖程度,即松耦合
3.便于测试
4.功能可复用(减少对象的创建和内存消耗)
5.使得程序的整个体系结构可维护性、灵活性、扩展性变高