二、Spring的“零配置”支持

搜索Bean类:

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

  • @Component:标注一个普通的Spring Bean类。
  • @Controller:标注一个控件器组件类。
  • @Service:标注一个业务逻辑组件类。
  • @Repository:标注一个业务DAO组件类

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类来处理,使用这两个元素需要指定如下两个属性:

  • type:指定过滤器类型。
  • expression:指定过滤器所需要的表达式。

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

  • annotation。
  • assignable。
  • regex。
  • aspectj。

如下配置文件指定所有以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来执行自动装配。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容