IOC
IOC即控制反转,是一种设计思想,就是将创建好的对象交给容器,控制对象的创建,传统的对象控制是直接进入对象所在的文件进行控制,而现在控制权限反转给IOC容器,这样就可以直接通过IOC对对象进行控制
Spring创建对象
applicationContext.xml文件下
<bean id="dog" class="ioc.Dog">
</bean>
<bean id="类名首字母小写" class="包名.类名"></bean>
Dog类
public class Dog implements Doginf{
public void jiao(){
System.out.println("旺旺!!");
}
}
实现了接口Doginf
Doginf
public interface Doginf {
String name="小白";
public void jiao();
}
Test
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
// 创建 Spring 的 IOC 容器
ClassPathXmlApplicationContext c = new ClassPathXmlApplicationContext("applicationContext.xml");
Doginf dog = (Doginf) c.getBean("dog");
System.out.print(dog.name + ":");
dog.jiao();
}
}
利用接口,spring能为我们解决硬编码的问题,当类名需要修改时,就可以去applicationContext.xml文件中修改类名,Dog类中的代码不需要修改,为我们对程序维护带来了方便。
IOC和DI
IOC的概念比较模糊,所以有人给出了一个新的名字:DI(依赖注入),他明确的描述了被依赖对象依赖IOC容器配置依赖对象
对个xml文件
复制applicationContext.xml文件到包中,然后改名,在主文件中调用他
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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">
<import resource="ioc/applicationContext_one.xml"/>//调用ioc/applicationContext_one.xml文件
</beans>
applicationContext_one.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">
<bean id="dog" class="ioc.Dog">
</bean>
</beans>
Bean管理
<bean id="dog" class="ioc.Dog" scope="singleton" lazy-init="false">singleton:单例设计模式, lazy-init是否延迟创建
</bean>
不写scope代表是单例设计模式
scope=“singleton” 单例的无论拿多少个对象,构造方法只走一次,且对象的内存地址都是相同的
这次调用是这个对象,下次在调用也是这个对象
当scope=singleton :根据bean标签的lazy-init属性值选择创建时间
scope=“prototype” 每次都创建一个新的对象,构造方法走多次,且对象的内存地址都是不相同的
每次调用都是新的对象
当scope=prototype:每次获取对象实例时(getBean()),spring都会新创建一个对象实例。
bean的初始化时间
其实就是spring创建javabean的时间
scope=“prototype” 创建javabean的时间,每次获取对象实例时,都会创建
.getBean(“dog”);每次这步都会创建一个对象
scope=“singleton” 根据bean标签的属性值来选择创建时间
scope=“singleton” lazy-init=“true” 单例的,且延迟创建对象
.getBean(“dog”);这步才创建对象
scope=“singleton” lazy-init=“false” 单例的,非延迟创建对象,在类被容器加载时就创建了
如果不写lazy-init代表false,被容器加载时就创建。
Scope和lazy-init一起使用
依赖注入
依赖注入分为手动注入和自动匹配
手动注入又分为构造方法和setter
由外部容器动态地将依赖对象注入到另一个对象的组件中。
Spring采用这种方式为bean属性赋值
简单的说,spring容器不仅可以初始化对象,也可以为对象当中的成员变量赋值,初始化成员变量对象以及赋值的过程,不需手动编码,而由spring容器去完成,这种依赖容器初始化对象,并赋值给bean全局变量的方式叫依赖注入。
手动注入
setter方法注入:Spring容器调用bean组件中的属性对象的set方法完成属性注入(赋值)
同样可以为基本类型(基本本类型的封装类型,String ,StringBuffer)18 种,bean组件类型,集合类型赋值。
根据属性的不同类型,可以分为三种注入方式:
1)基本类型注入
2)Spring组件类型注入
3)集合类型注入
applicationContext.xml文件
<property name="dog" ref="dog"></property> <!-- spring bean组件的注入 -->
<property name="likes" > <!-- spring 集合类型List的注入 注意有先后顺序 -->
<list>
<value type="java.lang.String">打篮球 </value>
<value type="java.lang.String">踢足球 </value>
<!--ref bean="cat"/-->
</list>
</property>
<property name="likesset" > <!-- spring 集合类型Set的注入 注意没有先后顺序 -->
<set>
<value type="java.lang.String">打游戏 </value>
<value type="java.lang.String">聊天</value>
<!--ref bean="cat"/-->
</set>
</property>
<property name="scoremap" > <!-- spring 集合类型Map的注入 注意没有先后顺序 -->
<map>
<entry key="语文" value="100"> </entry>
<entry key="数学" value="90"> </entry>
<!--entry key-ref="bean" value-ref=""></entry-->
</map>
</property>
</bean>
Test调用
package ioc;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap.KeySetView;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
// 创建 Spring 的 IOC 容器
ClassPathXmlApplicationContext c = new ClassPathXmlApplicationContext("applicationContext.xml");
Body bo = (Body) c.getBean("body");
System.out.println(bo.getName() + " " + bo.getAge());
List<String> list = bo.getLikes();
for (String s : list) {
System.out.println(s);
}
Set<String> set = bo.getLikesset();
for (String f : set) {
System.out.println(f);
}
Map map = bo.getScoremap();
Set s = map.keySet();
Iterator<String> it = s.iterator();
while (it.hasNext()) {
String key = it.next();
String value = (String) map.get(key);
System.out.println(key + " " + value);
}
}
}
实体类
package ioc;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Body {
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;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public List getLikes() {
return likes;
}
public void setLikes(List likes) {
this.likes = likes;
}
public Set<String> getLikesset() {
return likesset;
}
public void setLikesset(Set<String> likesset) {
this.likesset = likesset;
}
public Map<String, String> getScoremap() {
return scoremap;
}
public void setScoremap(Map<String, String> scoremap) {
this.scoremap = scoremap;
}
private Dog dog;
private List likes;
private Set<String> likesset;
private Map<String, String> scoremap;
}
注解
那我们要把我们的类给Spring的容器来管理,那就需要在类上加如下几个类的注解:
@Service:用于标注业务层组件、
@Controller:用于标注控制层组件(如struts中的action)、
@Repository:用于标注数据访问组件,即DAO组件。
@Component:泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
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">
<context:component-scan base-package="com.chinasofti"></context:component-scan>
<!-- 这里什么也不用加,是通过注解方式让类自动进入Spring容器中,让Spring进行管理的 -->
</beans>
@Component(value=“boy”)
public class Boy {
@Value(value="张三")
private String name;
@Value(value="10")
private int age;
@Resource(name="dog")
private Dog dog;
Set get 方法
}
1)@Component(value=“boy”) 相当于把Boy加入Spring容器中,并起名叫boy
2)@Value(value=“张三”) 相当于setter方式,给成员变量赋值为张三
3)@Resource(name=“dog”)相当于
<bean id = "boy" class="com.chinasofti.Boy">
<property name="dog" ref="dog"></property>
</bean>
总结:注解使用可以代替配置文件,不过,这种注解的方式不适合应用在大项目中,因为@Component(value=“boy”)boy有可能会相同。
注:
@Component(value=“boy”)创建出来的对象是单例设计模式
变成非单例的要在类前面加
@Scope(value=“prototype”)