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;
    }
}
  1. 根据索引注入
  2. 根据类型注入
  3. 根据参数名注入
<!--通过索引注入-->
<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容器中

转载于:https://my.oschina.net/u/189332/blog/518562

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值