#一、依赖注入 ##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容器中