对Spring IOC容器相关整理(二)

1、命名空间 :Beans 下的元素及属性

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" >
    <description>rabbitmq 连接服务配置</description>
    <!--步骤1、配置链接工厂-->
    <bean id="connectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
        <property name="host" value="${mq.address}"/>
        <property name="port" value="${mq.port}"/>
        <property name="password" value="${mq.pwd}"/>
        <property name="username" value="${mq.user}"/>
        <property name="publisherConfirms" value="true"/>
        <property name="publisherReturns" value="true"/>
        <property name="virtualHost" value="${mq.vhost}"/>
        <property name="requestedHeartBeat" value="50"/>
    </bean>
 //.......
</beans>

对于配置XML文件 Spring 提供了很多的元素和属性,用于对对象与其依赖关系进行描述。Spring的XML文件就像一张记录详细配料,火候等的菜谱。对于Spring XML文件,我们一般通过以<beans>....</beans>包围的元素开始配置。

有关http://www.springframework.org/schema/beans 中对于beans 的定义可参见:标签系列一:spring 中beans解释以及beans标签里面的属性

接下来我要整理一下关于beans 的相关的元素及属性:

beans命名空间下的元素

通过编辑器可以轻易的找到在beans命名空间下,存在beans、bean、alias、description、import 五个元素存在。(也可能是4个, 在http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 版中没有beans元素,4.0版存在(默认最新版请把上文中的-3.0 去掉))

1.1、beans元素

beans元素是顶层(通常为根)元素。允许定义所有嵌套bean定义的默认值。

beans元素有自己的属性:

1.1.1、default-autowire 属性:

default-autowire 有五个值 分别如下:

默认的值为:no 即不启用自动注入。

default:实际上是会优先执行constructor然后是byType

byType:这个是会根据类型去注入,当找到了会直接注入,没有找到不会报错,但是找到多个会报No unique bean of type的错误

byName:这个会根据name注入

constructor:这个是通过构造注入

no:不启用自动注入

1.1.2、default-autowire-candidates 属性:

 default-autowire-candidates是候选者,自动装配时即匹配则被包含。不匹配的排除在外。

default-autowire-candidates属性的值允许使用模式字符串,例如我们制定default-autowire-candidates=“*abc”,则所有以“abc”结尾的Bean都将被自动装配。它还支持多个字符,可以通过,空格 等分割。

1.1.3、default-init-method 和 default-destroy-method 属性:

default-init-method="init" default-destroy-method="destroy"

 很多Bean都需要配置初始化方法和销毁方法,那么可以在beans标签中配置default-init-method和default-destroy-method来指定所有Bean的默认初始化方法和销毁方法 (initdestroy 是bean中的方法)

 1.1.4、default-lazy-init 属性:

spring配置默认default-lazy-init为false,当属性default-lazy-init设置成true时,sping不会再去加载整个对象实例图,大大减少了初始化的时间,减少了spring的启动时间。

1.1.5、default-merge 属性:

 从Spring 2.0M2开始,beans支持default-merge= "true" 的定义,子类不需要重新定义父类的List型属性中已定义过的内容 

1.1.6、profile 属性:

将程序从一个环境迁移或切换到另一个环境 定义环境名称。

默认上下文中,添加spring.profiles.default的配置,如下:

<context-param>

    <param-name>spring.profiles.default</param-name>

    <param-value>development</param-value>

</context-param>

而对于spring.profiles.default,这里需要说明下:在Spring的Profile中,Profile存在两种状态,一种为默认加载的profile(spring.profiles.default),一种为指定激活的profile(spring.profiles.active)。如果程序未指定active状态的profile,那么执行default状态的profile,如果两种状态都指定,则优先执行或选择active状态的profile。


1.2、alias 元素(别名)

在对bean进行定义时,除了使用id属性来指定名称之外,为了提供多个名称,可以使用alias标签来指定。而所有的这些名称都指向同一个bean,有时我们期望能在当前位置为那些在别处定义的bean引入别名。在XML配置文件中,可用单独的<alias/>元素来完成bean别名的定义。如:

配置文件中定义了一个JavaBean

<bean id="resourceHolder" class="com.zk.demo1025.ResourceHolder"> </bean>

我要给这个JavaBean增加别名,以方便不同对象来调用。我们就可以这样写:

<alias name="resourceHolder" alias="resourceHolder1"/>

<alias name="resourceHolder" alias="resourceHolder2"/>

<alias name="resourceHolder" alias="resourceHolder3"/>


    <alias name="resourceHolder" alias="resourceHolder1,resourceHolder2,resourceHolder3"/>

或者是用name属性来指定,如:

<bean id="resourceHolder" name="resourceHolder1,resourceHolder2,resourceHolder3 " class="com.zk.demo1025.ResourceHolder"> </bean>

1.3、description (描述)元素

description元素必须在beans 中的第一行,用于描述配置的信息。

1.4 import 元素

在Spring的配置文件,有时候为了分模块的更加清晰的进行相关实体类的配置。引入其他模块XML

当使用import元素时会提供一下选项:

其中,以 .xml 结尾的是项目中的配置文件。

1.默认情况下,使用相对路径来辅助查找配置文件

2.Spring提供了四种前缀标记来辅助查找配置文件:

  (1)[classpath:]:表示从classpath开始寻找后面的资源文件

  (2)[file:]:表示使用文件系统的方式寻找后面的文件(文件的完整路径)

  (3)[classpath*:]:表示不仅会在class路径中去查找文件,还会在jar中去查找文件

  (4)[http:] :表示通过网络地址查找文件


注:classpath:XXXXX:相当于/WIN-INF/classes/xxxxx

1.5、bean 元素

bean元素的属性有很多:

常用属性有:

  • id , id标签是bean的唯一标识,IoC容器中bean的id标签不能重复,否则报错。
  • name ,name是bean的名称标识,IoC容器中bean的name标签不能重复同一个bean中可以与id 重复(没有发现不良反应)
  • class ,class属性是bean常用属性,为bean的全限定类名,指向classpath下类定义所在位置
  • factory-method ,factory-method工厂方法属性,通过该属性,我们可以调用一个指定的静态工厂方法,创建bean实例
  • factory-bean ,factory-bean就是生成bean的工厂对象,factory-bean属性和factory-method属性一起使用
  • init-method ,init-method属性是bean的初始方法,在创建好bean后调用该方法
  • destory-method ,destory-method属性是bean的销毁方法,在销毁bean之前调用该方法,一般在该方法中释放资源
  • scope,scope属性表示bean的作用范围(参见:对Spring IOC容器相关整理(一)
  • autowire ,autowire表示bean的自动装配

 id标签的值 在 同一个配置文件中是惟一的,在多个spring文件中存在相同的id 或 name后面引入的配置会覆盖前面的bean

其余属性有:

  • parent ,spring 中parent标签是指:某个<bean>的父类。这个类可以覆盖parent的属性
  • abstract ,使用abstract 属性 定义公共的属性。bean使用abstract=true时,可以有class,也可以没有class,一般与parent 配合使用。
  • autowire -candidate,值有 true, false、default  。autowire-candidate="false" 表示该对象不参与自动注入
  • depends-on , depends-on适用于表面上看起来两个bean之间没有使用属性之类的强连接的bean,但是两个bean又确实存在前后依赖关系的情况,被depends-on链接的bean 先创建,后销毁,依赖他人的bean是先于被依赖bean销毁的
  • lazy-init , 只有 true、false 用来指定bean是否在容器启动时初始化,为false时容器启动时初始化  用途: 通常用于解决spring循环引用的问题:
  • primary ,primary的值有true和false两个可以选择。默认为false。当一个bean的primary设置为true,然后容器中有多个与该bean相同类型的其他bean,此时,当使用@Autowired想要注入一个这个类型的bean时,就不会因为容器中存在多个该类型的bean而出现异常。而是优先使用primary为true的bean。不过,如果容器中不仅有多个该类型的bean,而且这些bean中有多个的primary的值设置为true,那么使用byType注入还是会出错。

1.5.1、bean元素的子元素

 

由上图可以看到,bean元素中有7子元素

  • property:通过setter对应的方法注入 。spring配置中property作为bean的属性。也就是指一个类中的成员。同时这个成员必须有set方法。
  • description :描述,一个字符串,没什么好说的。
  • constructor-arg :通过构造函数注入
  • lookup-method :方法的覆盖。注入bean的作用域小于当前bean时,希望每次可以拿到最新的注入bean。
  • meta:一个额外的属性,可以使用  BeanDefinition的getAttribute(key);方法获取,
  • qualifier:当bean的注入项有多个实现时,使用Qualifier指定要注入的bean的标识
  • replaced-method:方法的替换 ,要实现spring的MethodReplacer接口
  • 下面对每个元素进行详细介绍:

a、property 设值注入

property 元素属性有 name、 ref 、value 三个。 其中 name 为类中要注入依赖项的名字。需要有set方法。name值与setXXX 中XXX一致,与声明的名字无关。

ref 为引用项bean的id 或name 。value 值为值类型

property 元素有以下子元素:

 ref: <property name="....." ref="......" />就是找当前配置文件里的bean ,<ref bean ="....."/> 是寻找全局(可以到其他xml中)中的 bean;<ref>标签里 有3种属性 <ref bean="寻找全局(可以到其他xml中)中的 bean"/>,<ref local="关联当前xml的bean "/>,<ref parent="用于指定其依赖的父 JavaBean 定义"/>。4.0BeanXSD中 ref 元素上的local 属性不再受支持

bean: 内部 Bean:当 Spring IoC 容器中的 bean1 只会被 bean2 引用,而不会被容器中任何其他 Bean 引用的时候,则可以将这个 bean1 以内部 Bean 的方式注入到 bean2 中。

description: 描述,一个字符串

value: 为属性注入字面值

set: 当属性为 java.util.Set 的时候  可以在集合上加 merge="true",允许与父类集合合并

<bean id="boss" class="***">
  <property name="favorites">
    <set>
      <value>唱歌</value>
      <value>运动</value>
      <value>读书</value>
    </set>
  </property>
</bean>

array:当属性为 java.util.Array 的时候  可以在集合上加 merge="true",允许与父类集合合并

        <property name="favs">
            <array>
                <value>足球</value>
                <value>篮球</value>
                <value>排球</value>
            </array>
        </property>

idref: idref元素只是一种防止错误的方法,可以将容器中另一个beanid(一个字符串值,而不是引用)传递给一个<constructor-arg/><property/>元素(在某种意义上等同于<value/>)

<bean id="theTargetBean" class="..."/>

<bean id="theClientBean" class="...">
<property name="targetName">
<idref bean="theTargetBean"/>
</property>
</bean>

list: 当属性为 java.util.List 的时候,可以在集合上加 merge="true",允许与父类集合合并

<bean id="boss" class="***">
  <property name="favorites">
    <list>
      <value>唱歌</value>
      <value>运动</value>
      <value>读书</value>
    </list>
  </property>
</bean>

map: 当属性为 java.util.Map 的时候 可以在集合上加 merge="true",允许与父类集合合并

<bean id="boss" class="***">
  <property name="favorites">
    <map>
      <entry>
        <key><value>key01</value></key>
        <value>唱歌</value>
      </entry>
      <entry>
        <key><value>key02</value></key>
        <value>运动</value>
      </entry>
      <entry>
        <key><ref bean="keyBean" /></key>
        <ref bean="valueBean" />
      </entry>
    </map>
  </property>
</bean>

meta: 一个额外的属性,可以使用  BeanDefinition的getAttribute(key);方法获取,

<meta key = "key" value = "values">

null: 需要为某个 bean 的属性注入一个 null 值,在这里我们需要使用专用的 <null/> 元素标签,通过它可以为其他对象的属性注入 null 值。

props: 当属性为 java.util.Properties 的时候 可以在集合上加 merge="true",允许与父类集合合并

<bean id="boss" class="***">
  <property name="favorites">
      <props>
        <prop key="p01">唱歌</prop>
        <prop key="p02">运动</prop>
        <prop key="p03">读书</prop>
      </props>
    </properties>
  </property>
</bean>

 b、constructor-arg 构造注入

如下图,constructor-arg 有如下属性:

  • value :注入的字面值
  • ref:注入对其他bean的引用
  • name:注入项的名称
  • index:注入项在参数列表的序列号(从0开始)
  • type:注入项的类型

constructor-arg下的子元素如下:

与 property 属性相同,不在赘述。

 c、lookup-method 方法注入

 可以不是 抽象类型的方法

public abstract class FathorCarService {



    public void read(){
        CarService carService=look();
        System.out.println("睡觉,吃法,上班");
        carService.read();
    }

    protected abstract CarService look();

}


public class CarService {
    public void read(){
        System.out.println("读书,看报,写字");
    }


}


    public static void main(String[] args) {
        ClassPathXmlApplicationContext cx=new ClassPathXmlApplicationContext("classpath:spring/spring-config.xml");
        FathorCarService carService=(FathorCarService)cx.getBean("car2");
        carService.read();
    }



    <bean id="car" class="service.CarService" scope="prototype"/>
    <bean id="car2" class="service.FathorCarService">
        <lookup-method name="look" bean="car"/>
    </bean>

 如:

    protected  CarService look(){
        return null;
    }

同样可以进行方法注入。结果如下:

官方文档中 注入方法签名:

  1. public|protected要求方法必须是可以被子类重写和调用的;
  2. abstract可选,如果是抽象方法,CGLIB的动态代理类就会实现这个方法,如果不是抽象方法,就会覆盖这个方法,所以没什么影响;
  3. return-type就是non-singleton-bean的类型咯,当然可以是它的父类或者接口。
  4. no-arguments不允许有参数。

 d、replaced-method 方法替换

public  class FathorCarService {



    public void read(){
        CarService carService=look();
        System.out.println("睡觉,吃法,上班");
        carService.read();
    }

    protected  CarService look(){
        return null;
    }

}



public class CarService implements MethodReplacer {
    public void read(){
        System.out.println("读书,看报,写字");
    }


    @Override
    public Object reimplement(Object obj, Method method, Object[] args) throws Throwable {
        System.out.println("遛狗,跳绳,跑路");
        return null;
    }
}


    public static void main(String[] args) {
        ClassPathXmlApplicationContext cx=new ClassPathXmlApplicationContext("classpath:spring/spring-config.xml");
        FathorCarService carService=(FathorCarService)cx.getBean("car2");
        carService.read();
    }


    <bean id="car" class="service.CarService" scope="prototype"/>
    <bean id="car2" class="service.FathorCarService">
        <replaced-method name="read" replacer="car"/>
    </bean>

使用方法替换将本应该输出

输出为:

 大概就这么多了,如果有什么疏漏的地方,望各位博友指出.....

原文地址:https://www.cnblogs.com/hxz-nl/p/11069777.html