1.spring 控制反转介绍:
控制反转IOC(Inversion of Control),是一种包装技术类型,它本身不属于新的内容,说的再简单一点,所有对象的实例化操作都不再使用关键字new了(反射机制)。那么为什么现在的代码之中需要编写控制反转的操作呢?为了更好的解释这个问题.下面编写一个实际的程序分析。
如果员工出差,那么员工所需要做的核心处理--办理核心的操作业务,出差的目的,但是发现,要想实现这个目的现在有了困难,所有的一切都要求用户自己来负责处理。那么这样的操作形式就好比最早自己手工编写代码的时候必须明确的处理关键字new一样。
范例:传统代码问题
interface Fruit{
public void eat();
}
class Apple implements Fruit{
@Override
public void eat() {
System.out.println("吃苹果");
}
}
public class TestDomeA {
public static void main(String[] args) {
Fruit f = new Apple();
f.eat();
}
}
但是现在的问题在于耦合度加深了,因为某一个接口必须要与一个子类产生关联。
如果中间出现了代理公司,那么整个操作的过程之中,员工只需要自己去跟代理公司操作就可以完成所有与出差有关的业务处理,但是前提:用户依然需要关注代理公司的处理过程.
范例:好比代码之中使用了工厂设计模式
interface Fruit{
public void eat();
}
class Apple implements Fruit{
@Override
public void eat() {
System.out.println("吃苹果");
}
}
class Factroy{
public static Fruit getFruit() {
return new Apple();
}
}
public class TestDomeA {
public static void main(String[] args) {
Fruit f = Factroy.getFruit();
f.eat();
}
}
加入工厂设计之后最大的优点在于,整个的代码在操作过程之中,只会与工厂类发生耦合,工程想想成代理公司,这个代理公司需要开发者明确使用.
现在的"管理部门"就属于整个代码的运行容器,只要在这个容器里面运行的操作都可以得到相应的辅助操作支持.
那么这就属于IOC的操作,所有的辅助控制都交由容器完成.
2.应用操作:
开发工具:myeclipse2015
1.首先创建一个web项目,然后右击项目添加spring支持:
询问是否创建application.xml文件
然后选择要使用的开发包,本次不属于其框架的整合,所以直接使用默认的配置。
项目配置成功。
范例:1.定义操作接口
package com.jcn.demo;
public interface IFruit {
public void eat();
}
2.定义接口操作子类:
package com.jcn.demo;
public class Apple implements IFruit {
@Override
public void eat() {
System.out.println("吃苹果");
}
}
而随后不再提供有工厂操作类,因为spring本身就是一个工厂类。在以后的开发都不需要创建工厂类了。
3.配置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">
<bean id="apple" class="com.jcn.demo.Apple"/>
</beans>
随后下面要通过特定的模式启动spring容器。
范例:4.找到Apple类对象
值得发现的是:
类上标志的s,说明该类配置spring管理。
package com.jcn.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.jcn.demo.Apple;
import com.jcn.demo.IFruit;
public class TestFruit {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
IFruit fruit = ctx.getBean("apple" , Apple.class);
fruit.eat(); //只关心核心的业务操作方法
}
}
运行结果:
整个代码操作过程之中,无法发现工厂设计模式的明确使用,因为所有的工厂都由Spring帮助用户自动处理了,而且在applicationContext.xml文件配置的信息内容,都在Spring容器启动的时候默认的实例化好了所有的对象,用的时候,根据id名称取出即可。
而在编写代码过程之中也使用到了几个类。
1.ApplicationContext类(应用上下文类):org.springframework.context.ApplicationContext
所有在applicationContext.xml文件中配置的信息都需要通过此类读取才可以。
常用方法:
1. public <T> T getBean(java.lang.String name,
java.lang.Class<T> requiredType)
throws BeansException
取得指定名称的Bean对象,并且设置泛型为指定操作的Bean类型,避免向下转型。
最早的操作 public java.lang.Object getBean(java.lang.String name) 由于有向下转型,所以不使用此方法了。
throws BeansException
2.现在由于资源控制文件可能在任意的位置上,例如:CLASSPATH 中或者是在文件磁盘中,那么就必须使用相关的子类:
org.springframework.context.support.ClassPathXmlApplicationContext (在CLASSPATH中读取资源文件)
所有在spring中配置的<bean>元素都表示在Spring容器启动的时候自动就行初始化。
所以在使用对象之前已经准备好供用户操作的对象实例。
如果现在有更严格的配置也可以将接口配置进去。(一般不需要这么操作)。
范例:更完善的配置
<bean id="fruit" class="com.jcn.demo.IFruit" abstract="true"/>
<bean id="apple" class="com.jcn.demo.Apple" parent="fruit"/>
由于接口是抽象的,那么就表示接口对象不会进行实例化,而在编写“apple”元素的 时候加上的parent,实际上也只是个说明而已,加不加没有任何的影响。
总结:
所有的对象实例化等辅助部分不再需要由用户自己负责处理了,全部交给spring完成了,用户只需要根据自己需求引用对象实例即可。