二、Spring的“零配置”支持

2017-03-05  本文已影响478人  数独题

搜索Bean类:

Spring提供如下几个Annotation来标注Spring Bean:

Chinese.java

package entity;


import org.springframework.stereotype.Component;

import inter.Axe;
import inter.Persion;


@Component
public class Chinese implements Persion{

    private Axe axe;
    public void setAxe(Axe axe)
    {
        this.axe=axe;
    }
    @Override
    public void useAxe() {
        
        System.out.println(axe.chop());
    }
}

SteelAxe.java

package entity;

import org.springframework.stereotype.Component;

import inter.Axe;

@Component
public class SteelAxe implements Axe{

    @Override
    public String chop() {
        return "钢斧砍柴真快!";
        
    }

}

beans.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
        <!-- 自动扫描指定包及其子包下的所有Bean类 -->
        <context:component-scan base-package="entity"/>
      
</beans>

BeanTest.java

package test;

import inter.Persion;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanTest {

    public static void main(String[] args) 
    {
        ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
        System.out.println("------------"+java.util.Arrays.toString(ctx.getBeanDefinitionNames()));
    }
    
}

输出

------------[chinese, steelAxe, 
org.springframework.context.annotation.internalConfigurationAnnotationProcessor, 
org.springframework.context.annotation.internalAutowiredAnnotationProcessor, 
org.springframework.context.annotation.internalRequiredAnnotationProcessor, 
org.springframework.context.annotation.internalCommonAnnotationProcessor, 
org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor, 
org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor]

在基于XML配置方式下,每个Bean实例的名称都是由其id属性指定的;在这种基于Annotation的方式下,Spring采用约定的方式来为这些Bean实例指定名称,这些Bean实例的名称默认是Bean类的首字母小写,其他部分不变。

也可以在使用@Component标注时指定Bean实例名称:

@Component("axe")
public class SteelAxe implements Axe{
....................
}

默认情况下,Spring会自动搜索以@Component、@Controller、@Service、@Repository标注的Java类,并将他们当成Spring Bean来处理。还可以通过为<component-scan.../>元素添加<include-filter.../>或<exclude-filter.../>子元素来指定Spring Bean。<include-filter.../>子元素指定满足该规则的Java类会被当成Bean类来处理,<exclude-filter.../>子元素指定满足该规则的Java类不会被当成Bean类来处理,使用这两个元素需要指定如下两个属性:

Spring内建支持如下4中过滤器:

如下配置文件指定所有以Chinese结尾的类、以Axe结尾的类都将被当成Spring Bean处理:
beans.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
        <context:component-scan base-package="entity">
           <context:include-filter type="regex" expression=".*Chinese"/>
           <context:include-filter type="regex" expression=".*Axe"/>
        </context:component-scan>
      
</beans>

指定Bean的作用域:

使用@Scope来指定作用域
SteelAxe.java

//指定该Bean实例的作用域为propertype
@Scope("prototype")
//指定该类作为Spring Bean,Bean实例名为axe
@Component("axe")
public class SteelAxe implements(){........}

另外的方法:
beans.xml

<beans>
...
<context:component-scan base-package="entity" scope-resolver="config.MyScopeResolver" />
...
</beans>

使用@Resource配置依赖:

使用@Resource与<property.../>元素的ref属性有小童的效果。
Chinese.java

package entity;


import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import inter.Axe;
import inter.Persion;


@Component
public class Chinese implements Persion{

    private Axe axe;
    //axe的setter方法
    @Resource(name="steelAxe")
    public void setAxe(Axe axe)
    {
        this.axe=axe;
    }
    @Override
    public void useAxe() {
        
        System.out.println(axe.chop());
    }
}

@Resource不仅可以修饰setter方法,也可以修饰实例变量,此时Spring将会直接使用Java EE规范的Field注入,此时了setter方法都可以不要。
Chinese.java

package entity;


import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import inter.Axe;
import inter.Persion;


@Component
public class Chinese implements Persion{

        //执行Field注入
       @Resource(name="steelAxe")
    private Axe axe;
    @Override
    public void useAxe() {
        
        System.out.println(axe.chop());
    }
}

使用@PostConstruct和@PreDestroy定制生命周期行为:

@PostConstruct和@PreDestroy都用于修饰方法,前者修饰的方法是Bean的初始化方法,而后者修饰的是Bean销毁之前的方法。
Chinese.java

package entity;


import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import inter.Axe;
import inter.Persion;


@Component
public class Chinese implements Persion{

    //执行Field注入
    @Resource(name="steelAxe")
    private Axe axe;
    
    @Override
    public void useAxe() {
        
        System.out.println(axe.chop());
    }
    //初始化方法
    @PostConstruct
    public void init(){
        System.out.println("正在执行初始化的init方法....");
    }
    
    //销毁之前的方法
    @PreDestroy
    public void close()
    {
        System.out.println("正在执行销毁之前的close方法...");
    }
}

Spring3.0新增的注解:

@DespendsOn和@Lazy,@DespendsOn用于强制初始化其他Bean,@Lazy用于指定该Bean是否取消预初始化。
@DespendsOn可以修饰Bean类或方法,使用该注解时可以指定一个字符串数组做参数,每个数组元素对应一个强制初始化的Bean。

@DespendsOn({"steelAxe","abc"})
@Component
public class Chinese implements Persion{
.........
}

@Lazy修饰Spring Bean类用于指定该Bean的预初始化行为,使用该注解可以指定一个boolean型的value属相,用于决定是否要预初始化该Bean。

//不会预初始化Chinese Bean
@Lazy(true)
@Component
public class Chinese implements Persion{
.........
}

Spring4.0增强的自动装配和精确装配:

Spring提供了@Autowired注解来指定自动装配,@Autowired可以修饰setter方法、普通方法、实例变量和构造器等。当使用@Autowired标注setter方法时,默认采用byType自动装配策略。

@Component
public class Chinese implements Persion{
...
//axe的setter方法
public void setAxe(Axe axe){
  this.axe=axe;
  }
...
}

Spring将会自动搜索容器中类型为Axe的Bean实例,并将该Bean实例作为setAxe()方法的参数转入。

Spring还允许使用@Autowored来标注多个参数的普通方法。

@Component
public class Chinese implements Persion{
  ....
  //可接受多个参数的普通方法
 @Autowired  
public void prepare(Axe axe,Dog dog){
     this.axe=axe;
     this.dog=dog;
  }
}

当使用@Autowored修饰带多个参数的普通方法时,Spring会自动到容器中寻找类型匹配的Bean,如果恰好为每个参数都找到一个类型匹配的Bean,Spring会自动为这些Bean作为参数来调用该方法。

@Autowired用于修饰构造方法和实例变量。

@Component
public class Chinese implements Persion{
   @Autowired
   private Axe axe;
   @Autowired
   public Chinese(Axe axe,Dog dog){
    ......
   }
}

当使用@Autowired修饰一个实例变量是,Spring将会把容器中与该实例变量匹配的Bean设置为该实例的值。

@Autowired用于修饰数组类型的成员变量。

@Component
public class Chinese implements Persion{
  @Autowired
   private Axe[] axe;
...........
} 

Spring会自动搜索容器中所有的Axe实例,并以这些Axe实例作为数组元素来创建数组。

@Autowired也可标注集合类型的实例变量。

@Component
public class Chinese implements Persion{
    private Set<Axe> axes;
    @Autowired
    public void setAxes(Set<Axe> axes){
       this.axes=axes;
    }
}

Spring会自动搜索容器中的所用Axe实例,并将这些实例注入到axes实例变量中。

Spring提供了@Qualifier注解,通过使用@Qualifier,允许通过Bean的id来执行自动装配。

上一篇 下一篇

猜你喜欢

热点阅读