您的位置:首页 > 编程语言 > Java开发

Spring 依赖注入与Bean作用域

2015-10-18 00:00 561 查看
摘要: Spring 依赖注入与Bean作用域

#一、依赖注入
##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容器中
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: