Spring框架之SpringIoc容器(一)
来源:互联网 发布:5到8岁儿童服装店淘宝 编辑:程序博客网 时间:2024/05/16 05:20
SpringIoC,被称之为控制反转,是一个比较抽象的概念,对于初学者不太好理解,如下面的例子来说,通常我们创建对象时,会通过主动需求的方式来主动的创建一个实例对象,然而,控制反转则是通过将主动权转交给其它,这也是就是控制反转的概念;比如,我们做果汁的时候需要购买果汁机,橙子,准备白开水等,其实这些都是自己主动准备的过程,也就是说这杯果汁需要你主动的去创造,然而,现在你进需要通过微信等下单就可以的倒果汁,你并没有主动的去创造果汁,但是这样也达到了你的要求。
SpringIoC容器的设计主要是基于BeanFactory和ApplicaitonContext两个接口,其中ApplicationContext也是BeanFactory接口的一个子接口,也就是说,Spring最底层的接口为BeanFactory,其它的高级的接口则实现了对BeanFactory接口的功能的扩展,所以在大多数的情况下都会使用ApplicationContext作为Spring IoC容器,同时其扩展了很多的接口,例如WebApplicationContext,而具体的ApplicationContext则会在某个利于创造实现类在某一个领域使用,例如Spring MVC中的GenericWebApplicationContext就广泛的应用于java web工程之中。
为此我们可以看一下Spring中BeanFactory的源码:
public interface BeanFactory{Stirng FACTORY_BEAN_PREFIX = "&";Object getBean(String name) throws BeanException;<T> T getBean(Class<T> requiredType) throws BeanException;Object getBean(String name,Object...args)throws BeanException;<T> T getBean(Class<T> requiredType,Object...args) throws BeanException;boolean containsBean(String name);boolean isSingleton(String name) throws NoSuchBeanDefinitionException;boolean isPrototype(String name) throws NoSuchBeanDefinitionException;boolean isTypeMatch(Stirng name,ResolveableType typeToMatch) throws NoSuchBeanDefinitionException;boolean isTypeMatch(String name,Class<?> typeToMatch) throws NoSuchBeanDifinitionException;Class<?> getType(String name) throws NoSuchBeanDifinitonException;String [] getAliases(String name);}对于源码中的个体Bean()方法,从接口中的参数的类型来看,可以字符串也可以是Class类型,由于Class类型可以扩展接口也可以继承父类,所以在一定程度上会存在使用父类类型无法准确货的实例的异常,比如,有一个饮料类,有多个实现类,但是这个时候容器就无法判断获取哪个实现类的实例。
isSingleton是判断此实例是不是单例,是真,则这个容器中只有一个实例,而如果是prototype,则在每次调用时都会生成一个实例,一般的默认情况下是singleton模式。
我们通过一个实例来进行说明SpringIoc的过程:
首先添加必要的Spring框架的jar包,同时为了方便测试,我们是有JUnit测试类进行测试,所以也需要JUnit相关的Jar包。
我们首先模拟一下SpringIOC容器控制反转的概念,从容器中获取实例,而不是主动的去生成实例。
首先我们先设计一个UnitTestBase类实现读取spring的XML配置文件等,也同时设计了getBean方法,模拟最底层的BeanFactory接口的功能实现;before方法获取整个项目的配置,ClassPathXmlApplicationContext context的实例则在after方法中释放。
public class UnitTestBase {private ClassPathXmlApplicationContext context;private String springXmlpath;public UnitTestBase() {}public UnitTestBase(String springXmlpath) {this.springXmlpath = springXmlpath;}@Beforepublic void before() {if (StringUtils.isEmpty(springXmlpath)) {springXmlpath = "classpath*:spring-*.xml";}try {context = new ClassPathXmlApplicationContext(springXmlpath.split("[,\\s]+"));context.start();} catch (BeansException e) {e.printStackTrace();}}@Afterpublic void after() {context.destroy();}@SuppressWarnings("unchecked")protected <T extends Object> T getBean(String beanId) {try {return (T)context.getBean(beanId);} catch (BeansException e) {e.printStackTrace();return null;}}protected <T extends Object> T getBean(Class<T> clazz) {try {return context.getBean(clazz);} catch (BeansException e) {e.printStackTrace();return null;}}}
1.模拟控制反转的过程
首先设计一个接口OneInterface和对应的实现类OneInterfaceImpl类,设计如下:
public interface OneInterface {public void say(String arg);}对应的实现类:
public class OneInterfaceImpl implements OneInterface {public void say(String arg) {System.out.println("ServiceImpl say: " + arg);}}设计的对应的测试类为:
@RunWith(BlockJUnit4ClassRunner.class)public class TestOneInterface extends UnitTestBase {public TestOneInterface() {super("classpath*:spring-ioc.xml");}@Testpublic void testSay() {OneInterface oneInterface = super.getBean("oneInterface");oneInterface.say("This is a test.");}}通过调用父类UnitTestBase类的构造方法完成了TestOneInterface类的建立,借用OneInterface接口以及父类的getBean方法完成了SpringBean的获取,在测试方法testSay中实现了控制反转的理念,仅使用getBean()方法就可以获取相应类型的实例,在这里我们仅需要使用传递getBean方法的参数即可,不再需要使用new的主动创建对象的方法,在这里仅需说明使用哪个类型的对象或者是Bean的名字即可,就可以得到相应的对象。
Spring-ioc.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.xsd" > <bean id="oneInterface" class="....OneInterfaceImpl"></bean> </beans>
红色部分则定义类bean的名字为oneInterface,以及bean对应的实现类.
2.SpringBean的注入方式:
定义了一个模拟与数据库操作的流程,利用DAO的设计思想设计了DAO接口,实现类以及service接口及其实现类:
首先定义接口InjectionDAO,用于定义数据库底层操作的方法:
public interface InjectionDAO {public void save(String arg);}其实现类为InjectionDAOImpl:
public class InjectionDAOImpl implements InjectionDAO {public void save(String arg) {//模拟数据库保存操作System.out.println("保存数据:" + arg);}}定义InjectionService接口,用于声明业务逻辑所需的方法,可以在这个接口的实现类中完成复杂的业务逻辑:
public interface InjectionService {public void save(String arg);}其对应的实现类为:
public class InjectionServiceImpl implements InjectionService {private InjectionDAO injectionDAO;//构造器注入public InjectionServiceImpl(InjectionDAO injectionDAO1) {this.injectionDAO = injectionDAO1;}//设值注入public void setInjectionDAO(InjectionDAO injectionDAO) {this.injectionDAO = injectionDAO;}public void save(String arg) {//模拟业务操作System.out.println("Service接收参数:" + arg);arg = arg + ":" + this.hashCode();injectionDAO.save(arg);}}其中设置类两种bean的注入方式,由构造器或者setter方法设置;同时实现了所继承的save方法。
然而,体现不同的则是再配置文件spring-injection.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.xsd" > <!-- <bean id="injectionService" class="com.imooc.ioc.injection.service.InjectionServiceImpl"> --><!-- <property name="injectionDAO" ref="injectionDAO"></property> --><!-- </bean> --><bean id="injectionService" class="com.imooc.ioc.injection.service.InjectionServiceImpl"> <constructor-arg name="injectionDAO" ref="injectionDAO"></constructor-arg> </bean> <bean id="injectionDAO" class="com.imooc.ioc.injection.dao.InjectionDAOImpl"></bean> </beans>绿色所示的内容为,setter方式的注入,再InjectionServiceImpl类中需要一个injectionDAO类型的类的实例来完成InjectionServiceImpl这个类的实例化,所以再id为injectionService的类的injectionDAO参数则需要引用id为injectionDAO的bean来完成初始化。
红色部分为同构构造器的方式完成springbean的注入,通过使用标签<constructor-arg> 标签完成。
对应的测试类设计如下:
@RunWith(BlockJUnit4ClassRunner.class)public class TestInjection extends UnitTestBase {public TestInjection() {super("classpath:spring-injection.xml");}@Testpublic void testSetter() {InjectionService service = super.getBean("injectionService");service.save("这是要保存的数据");}@Testpublic void testCons() {InjectionService service = super.getBean("injectionService");service.save("这是要保存的数据");}}
- Spring框架之SpringIoc容器(一)
- springIOC容器(一)
- Spring学习记录一(SpringIOC容器初级)
- springIOC容器(二)
- Spring笔记之SpringIOC
- 【SSH进阶之路】Spring简介,搭建Spring环境——轻量级容器框架(一)
- 【SSH进阶之路】Spring简介,搭建Spring环境——轻量级容器框架(一)
- 【SSH进阶之路】Spring简介,搭建Spring环境——轻量级容器框架(一)
- 【SSH进阶之路】Spring简介,搭建Spring环境——轻量级容器框架(一)
- 【SSH进阶之路】Spring简介,搭建Spring环境——轻量级容器框架(一)
- Spring(三)SpringIOC
- 简易SpringIOC容器(初学)
- springIOC理解(一)
- SpringIOC容器
- springioc容器
- SpringIoC容器
- Spring之IoC容器解析(一)
- Java基础知识之容器(一:容器整体框架探索)
- 逻辑思维2
- PropertyPlaceholderConfigurer的用法
- Swift自定义类的存储
- 数据库Sharding的基本思想和切分策略
- Python与医疗图像5
- Spring框架之SpringIoc容器(一)
- sizeof的用法
- 逻辑思维4
- MYSQL数据库2
- Fiddler简介与Web抓包,远程抓包
- 组合数学-错排问题(转)
- Uiautomator自动化测试环境搭建eclipse+sdk+ADT
- jQuery学习二-设置
- FragmentTabHost+Fragment实现底部菜单栏