Spring 依赖注入与Bean作用域
2015-10-18 00:00
561 查看
摘要: Spring 依赖注入与Bean作用域
#一、依赖注入
##1.1、构造器注入
在容器实例化Bean时通过指定的Bean的构造器,注入依赖。还包括静态工厂和实例工厂方法。
###1.1.1、参数的注入方法
根据索引注入
根据类型注入
根据参数名注入
###1.1.2、静态工厂注入
###1.1.3、实例工厂注入
##1.2 setter注入
setter对于bean的限制:
bean必须要有要有一个__公共无参构造器__
属性建议设置为__private__访问级别
待注入属性要有一组__符合命名规则的setter和getter方法__
##1.3、方法注入
方法注入就是通过配置方法覆盖或拦截指定的方法。Spring是通过CGLIB动态代理方式实现方法注入,也就是通过修改字节码来实现的,本质是生成所需方法类的之类方式来实现。
###1.3.1、查找方法注入__(替换方法的返回结果)__
用于注入方法返回结果,通过配置的方式__替换方法的返回结果__
方法定义格式:方法访问级别__必须是public或者protected__,保证能被子类重载,可以是抽象方法,必须有返回值,必须是无参方法,查找方法的类和被重载的方法__必须非final__
__ public|protected [abstract] return-type theMethodName(no-arguments);__
###1.3.2、替换方法注入__(替换方法主体)__
和查找方法不一样的是,替换方法注入是用来替换方法主体,通过实现MethodReplacer接口来完成方法替换
#二、Bean作用域
Bean作用域在Spring容器中是创建的Bean对象对于其他Bean对象的请求可见范围。
##2.1 singleton作用域
作用域为singleton的Bean在每个Spring IoC容器中只存在一个实例,而且其生命周期完全由Spring容器管理。
<font color=red>__ bean的默认作用域为singleton__</font>
Spring对于单例的实现是通过注册表的方式实现:首先将需要单例通过唯一键注册到注册表,然后通过键来获取单例。
##2.2 prototype作用域
每次向Spring容器请求获取bean都返回一个全新的Bean,相对于“singleton”来说就是不缓存Bean。
##2.3 自定义作用域
自定义scope需要实现Spring的Scope接口,然后再通过xml注册到Spring容器中
#一、依赖注入
##1.1、构造器注入
在容器实例化Bean时通过指定的Bean的构造器,注入依赖。还包括静态工厂和实例工厂方法。
###1.1.1、参数的注入方法
public class Bean{ private String message; private int index; public Bean(String message, int index) { this.message = message; this.index = index; } }
根据索引注入
根据类型注入
根据参数名注入
<!--通过索引注入--> <bean id="indexInject" class="...Bean"> <constructor-arg index="0" value="Hello World!"/> <constructor-arg index="1" value="1"/> </bean> <!--通过类型注入--> <bean id="typeInject" class="...Bean"> <constructor-arg type="java.lang.String" value="Hello World!"/> <constructor-arg type="int" value="1"/> </bean> <!--通过参数名注入--> <bean id="typeInject" class="...Bean"> <constructor-arg name="message" value="Hello World!"/> <constructor-arg name="index" value="1"/> </bean>
###1.1.2、静态工厂注入
public class DependencyInjectByStaticFactory { public static Bean newInstance(String message, int index) { return new Bean(message, index); } }
<bean id="indexInject" class="...DependencyInjectByStaticFactory" factory-method="newInstance"> <constructor-arg index="0" value="Hello World!"/> <constructor-arg index="1" value="1"/> </bean>
###1.1.3、实例工厂注入
public class DependencyInjectByInstanceFactory{ public Bean newInstance(String message, int index){ return new Bean(message, index); } }
<bean id="instanceFactory" class="....DependencyInjectByInstanceFactory"/> <bean id="indexInject" factory-bean="instanceFactory" factory-method="newInstance"> <constructor-arg index="0" value="Hello World!"/> <constructor-arg index="1" value="1"/> </bean>
##1.2 setter注入
setter对于bean的限制:
bean必须要有要有一个__公共无参构造器__
属性建议设置为__private__访问级别
待注入属性要有一组__符合命名规则的setter和getter方法__
public class Bean{ private String message; private int index; public void setMessage(String message){ this.message = message; } public void setIndex(int index) { this.index = index; } }
<bean id="beanSetter" class="...Bean"> <property name="message" value="Hello World!"/> <property name="index" value="1"/> </bean>
##1.3、方法注入
方法注入就是通过配置方法覆盖或拦截指定的方法。Spring是通过CGLIB动态代理方式实现方法注入,也就是通过修改字节码来实现的,本质是生成所需方法类的之类方式来实现。
###1.3.1、查找方法注入__(替换方法的返回结果)__
用于注入方法返回结果,通过配置的方式__替换方法的返回结果__
方法定义格式:方法访问级别__必须是public或者protected__,保证能被子类重载,可以是抽象方法,必须有返回值,必须是无参方法,查找方法的类和被重载的方法__必须非final__
__ public|protected [abstract] return-type theMethodName(no-arguments);__
public class Printer { private int counter = 0; public void print(String type) { System.out.println(type + "printer:" + counter++); } public void print(String type, int id) { System.out.println(type + " " + id + " printer:" + counter++); } }
public abstract class HelloImpl5 implements HelloApi { private Printer printer; @Override public void sayHello() { printer.print("setter"); createPrototypePrinter().print("prototype"); createSingletonPrinter().print("singleton"); } // 被查找注入的方法1 public Printer createSingletonPrinter(){ System.out.println("该方法不会被执行,如果输出就错了。"); return new Printer(); } // 被查找注入的方法1 public abstract Printer createPrototypePrinter(); public void setPrinter(Printer printer) { this.printer = printer; } }
<bean id="prototypePrinter" class="cn.javass.spring.chapter2.helloworld.Printer" scope="prototype"/> <bean id="singletonPrinter" class="cn.javass.spring.chapter2.helloworld.Printer"/> <!--bean的默认scope为singleton--> <bean id="helloApi1" class="cn.javass.spring.chapter2.helloworld.HelloImpl5"> <property name="printer" ref="prototypePrinter"/> <lookup-method name="createPrototypePrinter" bean="prototypePrinter"/> <lookup-method name="createSingletonPrinter" bean="singletonPrinter"/> </bean> <bean id="helloApi2" class="cn.javass.spring.chapter2.helloworld.HelloImpl5" scope="prototype"> <property name="printer" ref="prototypePrinter"/> <lookup-method name="createPrototypePrinter" bean="prototypePrinter"/> <lookup-method name="createSingletonPrinter" bean="singletonPrinter"/> </bean>
###1.3.2、替换方法注入__(替换方法主体)__
和查找方法不一样的是,替换方法注入是用来替换方法主体,通过实现MethodReplacer接口来完成方法替换
public class PrinterReplacer implements MethodReplacer { //将替换掉Printer中的print(String message, int index)方法的内容 @Override public Object reimplement(Object obj, Method method, Object[] args) throws Throwable { System.out.println("Print Replacer"); return null; } }
<bean id="replacer" class="cn.javass.spring.chapter2.helloworld.PrinterReplacer"/> <bean id="printer" class="cn.javass.spring.chapter2.helloworld.Printer"> <replaced-method name="print" replacer="replacer"> <arg-type>java.lang.String</arg-type> <arg-type>int</arg-type> </replaced-method> </bean>
#二、Bean作用域
Bean作用域在Spring容器中是创建的Bean对象对于其他Bean对象的请求可见范围。
##2.1 singleton作用域
作用域为singleton的Bean在每个Spring IoC容器中只存在一个实例,而且其生命周期完全由Spring容器管理。
<font color=red>__ bean的默认作用域为singleton__</font>
Spring对于单例的实现是通过注册表的方式实现:首先将需要单例通过唯一键注册到注册表,然后通过键来获取单例。
##2.2 prototype作用域
每次向Spring容器请求获取bean都返回一个全新的Bean,相对于“singleton”来说就是不缓存Bean。
##2.3 自定义作用域
自定义scope需要实现Spring的Scope接口,然后再通过xml注册到Spring容器中
相关文章推荐
- java 排序算法
- 包办婚姻的Spring IoC
- Web版RSS阅读器(五)——初步完成阅读功能
- 一口一口吃掉Hibernate(三)——Hibernate给表和字段设置前后缀及分隔符
- struts标签+jstl标签之国际化实例
- 任务调度(一)——jdk自带的Timer
- 任务调度(二)——jdk自带的Timer 动态修改任务执行计划
- 一览Spring全貌
- 浅析Java中的反射机制原理
- Java反射机制与应用
- java初学者必看——J2SE小结
- 一口一口吃掉Hibernate(一)——使用SchemaExport生成数据表
- Spring Aop实例之xml配置
- java中使用反射获取pojo(实体)类的所有字段值
- javaweb:判断当前请求是否为移动设备访问
- 深入浅出了解Struts的处理流程(有图有真相)
- Struts 简单小结
- 3幅图让你了解Spring AOP
- java.lang.IncompatibleClassChangeError: Implementi
- Java反射API研究(2)——java.lang.reflect详细内容与关系