IoC—Inversion of Control,即“控制反转”,它不是什么技术,而是一种设计思想。在 Java 开发中, IoC意味着将设计好的对象交给容器控制,而不是传统的在对象内部直接控制。
传统Java程序中,咱们直接在对象内部经过new进行建立对象,是程序去主动建立依赖对象;而IoC是有专门的一个容器来建立这些对象,即由IoC容器来控制对象的建立。反转则是由容器来帮忙建立及注入依赖对象。
IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导咱们如何设计出松耦合、更优良的程序。传统应用程序都是由咱们在类内部主动建立依赖对象,从而致使类与类之间高耦合,难于测试;有了IoC容器后,把建立和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,因此对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得很是灵活。java
DI—Dependency Injection,即“依赖注入”:是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并不是为软件系统带来更多功能,而是为了提高组件重用的频率,并为系统搭建一个灵活、可扩展的平台。经过依赖注入机制,咱们只须要经过简单的配置,而无需任何代码就可指定目标须要的资源,完成自身的业务逻辑,而不须要关心具体的资源来自何处,由谁实现。
对于IoC和DI,其实它们是同一个概念的不一样角度的描述。web
IoC容器就是具备依赖注入功能的容器,IoC容器负责实例化、定位、配置应用程序中的对象及创建这些对象间的依赖。应用程序无需直接在代码中new相关的对象,应用程序由IoC容器进行组装。在Spring中BeanFactory是IoC容器的实际表明者。
在 Spring Ioc 容器的表明就是 org.springframework.beans 包中的BeanFactory 接口, BeanFactory 接口提供了 IoC 容器最基本功能;而org.springframework.context 包下的 ApplicationContext 接口扩展了 BeanFactory ,还提供了与Spring AOP 集成、国际化处理、事件传播及提供不一样层次的 context 实现 (如针对 web 应用的 WebApplicationContext )。简单说, BeanFactory 提供了 IoC 容器最基本功能,而 ApplicationContext 则增长了更多支持企业级功能支持。 ApplicationContext 彻底继承 BeanFactory ,于是 BeanFactory 所具备的语义也适用于 ApplicationContext。spring
Person.java编程
package com.liu5599.test; public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "name: " + name + " age: " + age; } }
Main.javasession
package com.liu5599.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Person p = (Person)context.getBean("person"); System.out.println(p); } }
spring.xmlide
<?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-3.0.xsd"> <bean id = "person" class = "com.liu5599.test.Person"> <property name="name" value="liuyang" /> <property name="age" value="21" /> </bean> <!--<bean id = "person" class = "com.liu5599.test.Person">--> <!--<property name="name">--> <!--<value>liuyang</value>--> <!--</property>--> <!--<property name="age">--> <!--<value>21</value>--> <!--</property>--> <!--</bean>--> <!--<bean id = "person" class = "com.liu5599.test.Person"--> <!--p:name = "liuyang" p:age = "21">--> </beans>
输出结果:函数
name: liuyang age: 21
接着讲述一个Bean中嵌套着另一个Bean。测试
1.第一种方式是在Student中经过ref属性引用Person的Bean,可是一旦Person被引用到了Student下,也就不会被其余的Bean引用了。this
2.第二种方式是在Student的Bean中声明一个内部的Bean。prototype
3.第三种方式是经过构造函数注入。
将测试类进行修改以下:
package com.liu5599.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Student p = (Student)context.getBean("student"); System.out.println(p); } }
输出结果:
Student name: liuyang age: 21
在Spring中,支持以下5种类型的做用域:
默认状况下,做用域是单例。
public class Message { private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Message m1 = (Message) context.getBean("message"); m1.setMessage("Message1"); System.out.println("Message1: " + m1.getMessage()); Message m2 = (Message)context.getBean("message"); System.out.println("Message2: " + m2.getMessage()); } }
输出结果:
Message1: Message1 Message2: Message1
<bean id = "message" class = "com.liu5599.test.Message" scope="prototype" />
运行结果:
Message1: Message1 Message2: null
这里主要讲述List、Set、Map和Properties四种集合类型。
Properties类型相似于特殊的Map,不一样之处是Map的key能够为任意类型对象,而Properties类型的key只能是字符串。
1.首先修改Student类,修改以下。
public class Student { private List<Object> lists; private Set<Object> sets ; private Map<Object, Object> maps ; private Properties pros; public List<Object> getLists() { return lists; } public void setLists(List<Object> lists) { this.lists = lists; } public Set<Object> getSets() { return sets; } public void setSets(Set<Object> sets) { this.sets = sets; } public Map<Object, Object> getMaps() { return maps; } public void setMaps(Map<Object, Object> maps) { this.maps = maps; } public Properties getPros() { return pros; } public void setPros(Properties pros) { this.pros = pros; } private Person person; public Student() {} public Student(Person person) { this.person = person; } public void setPerson(Person person) { this.person = person; } @Override public String toString() { return "Student " + person; } }
2.修改spring.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id = "person" class = "com.liu5599.test.Person"> <property name = "name" value = "liuyang" /> <property name = "age" value = "21" /> </bean> <bean id = "student" class="com.liu5599.test.Student"> <property name = "lists"> <list> <value>1</value> <ref bean = "person" /> <bean class = "com.liu5599.test.Person"> <property name = "name" value = "abc" /> <property name = "age" value = "20" /> </bean> </list> </property> <property name="sets"> <set> <value>1</value> <ref bean = "person" /> <bean class = "com.liu5599.test.Person"> <property name = "name" value = "abc" /> <property name = "age" value = "20" /> </bean> </set> </property> <property name="maps"> <map> <entry key = "key1" value = "123" /> <entry key = "key2" value-ref = "person" /> <entry key = "key3"> <bean class = "com.liu5599.test.Person"> <property name = "name" value = "abcd" /> <property name = "age" value = "19" /> </bean> </entry> </map> </property> <property name="pros"> <props> <prop key = "name">liuyang</prop> <prop key = "age">21</prop> </props> </property> <property name="person"> <bean class = "com.liu5599.test.Person"> <property name = "name" value = "liuyang" /> <property name = "age" value = "21" /> </bean> </property> </bean> <bean id = "message" class = "com.liu5599.test.Message" scope="prototype" /> </beans>
3.修改测试类,以下。
public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); Student s = (Student)context.getBean("student"); System.out.println(s.getLists().toString()); System.out.println(s.getSets().toString()); System.out.println(s.getMaps().toString()); System.out.println(s.getPros().toString()); } }
输出结果:
[1, name: liuyang age: 21, name: abc age: 20] [1, name: liuyang age: 21, name: abc age: 20] {key1=123, key2=name: liuyang age: 21, key3=name: abcd age: 19} {age=21, name=liuyang}
以上就是Spring Bean的简单使用方法,可是全都是手动配置的,难以维护,下次我会写一篇关于注解配置和自动扫描装配的文章。