参考文章:http://www.iteye.com/blogs/subjects/sPRing3?page=3
IOC:控制反转1.将设计好的对象交给容器控制,而不是传统的在你对象内部直接控制,创建和查找依赖对象的控制权交给容器2.不是一种技术,是一种思想,松耦合,方便进行测试DI:依赖注入 DI与IOC:1.IOC具有依赖注入功能的容器,容器动态的将某个依赖关系注入到组件之中,并非带来更多的功能,提升重用的频率2.同一个概念不一样角度的描述,控制反转控制对象一个层面,很难想到谁来维护对象的关系。依赖注入,明确描述了被注入对象依赖IOC容器配置依赖对象●谁依赖于谁:当然是应用程序依赖于IoC容器;●为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;●谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;●注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。
基本环境:
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.samlai.spring</groupId> <artifactId>spring</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>4.1.5.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <!-- Junit测试类 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies></project>1.hello world例子:
接口:
package spring.Tinterface;public interface HelloImp { public void hello();}实现类:package spring.realize;import spring.Tinterface.HelloImp;public class HelloRealize implements HelloImp{ public void hello() { System.out.println("Hello World!"); }}测试类:/** * applicationContext实例化对象 */ @Test public void ApContextTestHello(){ //读取配置文件实例化一个IOC容器 ApplicationContext context=new ClassPathXmlApplicationContext("hello.xml"); //从容器中获取对应的bean,注意此处"面向接口编程,而不是面向实现" HelloImp helloImp=context.getBean("hello",HelloImp.class); //执行业务逻辑 helloImp.hello(); System.out.println("ApplicationContext"); }BeanFactory:提供了IOC容器最基本的功能,可以从classpath或文件系统等获取资源而ApplicationContext则增加更多企业级功能支持,ApplicationContex完全继承BeanFactory
/** * BeanFactory实例化对象 */ @Test public void BeanFactoryTestHello(){ //1.ClassPathResource方式// Resource resource=new ClassPathResource("hello.xml"); //2.FileSystemResource方式 File file=new File("resource/hello.xml"); Resource resource=new FileSystemResource(file); BeanFactory beanFactory=new XmlBeanFactory(resource); //从容器中获取对应的bean,注意此处"面向接口编程,而不是面向实现" HelloImp helloImp=beanFactory.getBean("hello",HelloImp.class); //执行业务逻辑 helloImp.hello(); System.out.println("BeanFactory"); }2.Bean说明
Bean的配置:IOC目的:管理bean,这些Bean将根据配置文件进行创建,而Bean定义在容器内部由BeanDefinition对象表示,该定义要包含以下信息:●全限定类名(FQN):用于定义Bean的实现类;●Bean行为定义:这些定义了Bean在容器中的行为;包括作用域(单例、原型创建)、是否惰性初始化及生命周期等;●Bean创建方式定义:说明是通过构造器还是工厂方法创建Bean;●Bean之间关系定义:即对其他bean的引用,也就是依赖关系定义,这些引用bean也可以称之为同事bean 或依赖bean,也就是依赖注入。Bean定义只有“全限定类名”在当使用构造器或静态工厂方法进行实例化bean时是必须的,其他都是可选的定义。难道Spring只能通过配置方式来创建Bean吗?回答当然不是,某些SingletonBeanRegistry接口实现类实现也允许将那些非BeanFactory创建的、已有的用户对象注册到容器中,这些对象必须是共享的,比如使用DefaultListableBeanFactory 的registerSingleton() 方法。不过建议采用元数据定义。Bean的命名:每个Bean可以有一个或多个id(或称之为标识符或名字),在这里我们把第一个id称为“标识符”,其余id叫做“别名”;这些id在IoC容器中必须唯一。指定id和name,id就是标识符,而name就是别名,必须在Ioc容器中唯一使用<alias>标签指定别名,别名也必须在IoC容器中唯一实例化Bean:1.默认空构造器,<bean id="xxx" class="xxx">2.有参数构造器:在bean内配置+<constructor-arg>3.使用静态工厂方式实例化Bean,使用这种方式除了指定必须的class属性,还要指定factory-method属性来实例化Bean的方法,而且静态工厂方法也允许方法参数 Spring Ioc将调用此属性指定的方法来获取Bean 4.使用实例化方法实例化Bean,使用这种方式不能指定class属性,此时必须使用factory-bean属性来指定bean,factory属性指定实例化Bean方式,而且使用实例工厂 允许指定方法参数,方式和使用构造器方式一样
xml配置:
<!-- id是唯一标示符,其他id叫做别名 --> <bean id="helloOne" name="helloOne" class="spring.realize.HelloRealize"></bean> <!-- 构造器的配置文件 --> <!--使用默认构造参数--> <bean id="helloC1" class="spring.realize.HelloConstructorRealize"></bean> <!-- 指定构造器参数 --> <bean id="helloC2" class="spring.realize.HelloConstructorRealize"> <constructor-arg index="0" value="Hello Spring!"/> </bean> <!-- 使用静态工厂配置 --> <bean id="factoryHello" class="spring.realize.HelloFactory" factory-method="newIntance"> <constructor-arg index="0" value="Bean Factory Spring..." /> </bean> <!-- 实例化工厂bean创建bean --> <!-- 1.定义实例工厂Bean --> <bean id="beanInstanceFactoryHello" class="spring.realize.HelloInstanceFactory"></bean> <!-- 2.使用实例工厂Bean创建Bean --> <bean id="instanceBean" factory-bean="beanInstanceFactoryHello" factory-method="newInstance"> <constructor-arg index="0" value="Instance Spring!"></constructor-arg> </bean>实现类:
package spring.realize;import spring.Tinterface.HelloImp;public class HelloConstructorRealize implements HelloImp{ private String message; public HelloConstructorRealize(){ this.message="this is constructor Test."; } public HelloConstructorRealize(String message) { this.message = message; } public void hello() { System.out.println(this.message); } }package spring.realize;import spring.Tinterface.HelloImp;public class HelloFactory { //静态工厂的方法 public static HelloImp newIntance(String message){ return new HelloConstructorRealize(message); }}package spring.realize;import spring.Tinterface.HelloImp;//实例化工厂public class HelloInstanceFactory { public HelloImp newInstance(String message){ return new HelloConstructorRealize(message); }}测试类:/** * id与name进行对比 */ @Test public void IdAndNameTest(){ ApplicationContext context=new ClassPathXmlApplicationContext("hello.xml"); HelloImp helloImp=context.getBean("helloOne",HelloImp.class); helloImp.hello(); String[] alias=context.getAliases("helloOne"); //alias.length = 0 //因此别名不能和id一样,如果一样则由IOC容器负责消除冲突 System.out.println("alias.length = "+alias.length); Assert.assertEquals(0, alias.length); System.out.println("IdAndNameTest"); } /** * constructor构造器的建立 */ @Test public void ConstrouctTest(){ ApplicationContext context=new ClassPathXmlApplicationContext("hello.xml"); HelloImp h1=context.getBean("helloC1",HelloImp.class); HelloImp h2=context.getBean("helloC2",HelloImp.class); h1.hello(); h2.hello(); /* * 打印结果: * this is constructor Test. Hello Spring! */ System.out.println("ConstrouctTest"); } /** * 静态工厂Factory的测试 * */ @Test public void FactoryTest(){ ApplicationContext context=new ClassPathXmlApplicationContext("hello.xml"); HelloImp factoryBean=context.getBean("factoryHello",HelloImp.class); factoryBean.hello(); //打印:Bean Factory Spring... System.out.println("FactoryTest"); } /** * 实例化Factory的测试 * */ @Test public void instanceFactoryTest(){ ApplicationContext context=new ClassPathXmlApplicationContext("hello.xml"); HelloImp factoryBean=context.getBean("instanceBean",HelloImp.class); factoryBean.hello(); //打印:Instance Spring! System.out.println("instanceFactoryTest"); }
新闻热点
疑难解答