一、Spring IOC 简介
IOC(Inverse of control):控制反转,又称作依赖注入,主要是把创建对象和查找依赖对象的控制权交给IOC容器,由IOC容器管理对象的生命周期,是一种重要的面向对象编程的法则来消减计算机程序的耦合问题,是Spring框架的核心。
1、IOC例子说明
业务场景:员工工作,当有一份工作出现时,会有对应的人来做此工作,如果在工作中直接new出员工,这样工作和员工就绑定到一起了,然而正确的场景却不希望这样,工作只负责工作,人员应该由主管来确定。
例子:工作与员工绑定到一起了
//员工张三 public class Zhangsan { public void doWork() { System.out.println("张三开发"); } } //工作业务逻辑 public class DoWork { public void doWork() { Zhangsan zs = new Zhangsan(); zs.doWork(); } } public class SpringTest { //开发主管 @Test public void zhuguan() { DoWork dw = new DoWork(); dw.doWork()1; } }
例子:工作安排控制权交给主管
//员工逻辑 public interface Employee { void doWork(); } //员工张三 public class Zhangsan implements Employee{ public void doWork() { System.out.println("张三开发"); } } //工作业务逻辑 public class DoWork { private Employee user; public void setUser(Employee user) { this.user = user; } public void doWork() { user.doWork(); } } public class SpringTest { //开发主管 @Test public void zhuguan() { DoWork dw = new DoWork(); dw.setUser(new Zhangsan()); dw.doWork(); } }
这个控制由那位员工来开发权利可以交由spring控制,这样工作业务代码和员工就解耦了:
<?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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <bean id="zhangsan" class="top.ruandb.entity.Zhangsan"></bean> <bean id="doWork" class="top.ruandb.service.DoWork"> <property name="user" ref="zhangsan"></property> </bean> </beans> public class SpringTest { ApplicationContext ac ; @Before public void setUp() { ac = new ClassPathXmlApplicationContext("applicationContext.xml"); } @Test public void test1() { DoWork doWork = (DoWork) ac.getBean("doWork"); doWork.doWork(); } @After public void tearDown() { ac = null; } }
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" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <!-- 属性注入 --> <bean id="people" class="top.ruandb.entity.People"> <property name="name" value="张三"></property> <property name="age" value="18"></property> </bean> <!-- 构造函数注入;(通过类型) --> <bean id="people1" class="top.ruandb.entity.People"> <constructor-arg type="String" value="李四"></constructor-arg> <constructor-arg type="int" value="18"></constructor-arg> </bean> <!-- 构造函数注入;(通过索引) --> <bean id="people2" class="top.ruandb.entity.People"> <constructor-arg index="0" value="王五"></constructor-arg> <constructor-arg index="1" value="18"></constructor-arg> </bean> <!-- 构造函数注入;(类型和索引联合使用) --> <bean id="people3" class="top.ruandb.entity.People"> <constructor-arg type="String" index="0" value="赵六"></constructor-arg> <constructor-arg type="int" index="1" value="18"></constructor-arg> </bean> <!-- 工厂注入(非静态工厂) --> <bean id="peopleFactory" class="top.ruandb.factory.PeopleFactory"></bean> <bean id="people4" factory-bean="peopleFactory" factory-method="createPeople"></bean> <!-- 工厂注入(静态工厂) --> <bean id="people5" class="top.ruandb.factory.PeopleFactory2" factory-method="createPeople"></bean> <!-- 注入参数 --> <bean id="dog" class="top.ruandb.entity.Dog"> <property name="name" value="tom"></property> </bean> <bean id="people6" class="top.ruandb.entity.People"> <!-- 基本类型值 --> <property name="name" value="张三"></property> <property name="age" value="18"></property> <!-- 注入 bean参数(ref方式) --> <property name="dog" ref="dog"></property> <!-- 注入 bean参数(内部bean方式) --> <property name="cat"> <bean class="top.ruandb.entity.Cat"> <property name="name" value="lucy"></property> </bean> </property> <!-- 注入null --> <property name="nullString"> <null></null> </property> <!-- 注入List --> <property name="hobbys"> <list> <value>吃饭</value> <value>睡觉</value> </list> </property> <!-- 注入Set --> <property name="loves"> <set> <value>上班</value> <value>加班</value> </set> </property> <!-- 注入Map --> <property name="map"> <map> <entry> <key><value>1</value></key> <value>2</value> </entry> <entry> <key><value>3</value></key> <value>4</value> </entry> </map> </property> </bean> <!-- Spring默认的bean都是单例,可以通过配置 prototype ,实现多例.其他类通过某方法获取多例,方法注入 lookup-method --> <bean id="dog1" class="top.ruandb.entity.Dog" scope="prototype"></bean> <bean id="people6" class="top.ruandb.entity.People"> <lookup-method name="getDog" bean="dog1"/> </bean> <!-- bean关系 继承:parent;依赖:depends-on(依赖后会先初始化依赖的类);引用:ref --> <bean id="abstractPeople" class="top.ruandb.entity.People" abstract="true"> <property name="className" value="高三5班"></property> <property name="age" value="19"></property> </bean> <bean id="zhangsan" parent="abstractPeople" depends-on="autority"> <property name="id" value="1"></property> <property name="name" value="张三"></property> </bean> <bean id="lisi" parent="abstractPeople"> <property name="id" value="2"></property> <property name="name" value="李四"></property> <property name="age" value="20"></property> <!-- 引用dog --> <property name="dog" ref="dog"></property> </bean> <bean id="autority" class="top.ruandb.entity.Authority"></bean> <!-- bean的作用范围 scope 1,singleton Spring ioc 容器中仅有一个 Bean 实例,Bean 以单例的方式存在; 2,prototype 每次从容器中调用 Bean 时,都返回一个新的实例; 3,request 每次 HTTP 请求都会创建一个新的 Bean; 4,session 同一个 HTTP Session 共享一个 Bean; 5,global session 同一个全局 Session 共享一个 Bean,一般用于 Portlet 应用环境; 6,application 同一个 Application 共享一个 Bean; --> </beans>