spring注解简介

spring 注解


多选择是好事嘛?

Spring 经过十多年的快速发展和更新,以其独特的创新带来了大量的拥趸者,在选择方面还带来了更多选择!譬如spring bean的装配(在XML中进行显式配置、在Java中进行显式配置、隐式的bean发现机制和自动装配),注解的多元化(基本注解、jsr250、jsr330)等等!

而这么多重复的选择难道真的是好事吗?这是否也以为学习与成本提高,掌握的难度加大?
打个比喻:同样可以救国,某个叫spring的神经病告诉你可以从医救国(xml显式配置),当你学医正酣的时候,它又告诉你还可以从军救国(Java显示配置),当你练习擒拿射击快要成功的时候,它来告诉你,其实有更简单的方法可以教育救国(bean的自动装配)!
作为一个初学者,个人认为,从学 servlet 到 jsp 再到 struts 到现在的 spring ,坑是越挖越大越挖越多!

 

注解分类

spring自带注解:

 @Autowired、@Qualifier、@Value、@Primary、@Required、@Component、@Repository、@Service、@Controller

JSR-250注解:

@Resource、@PostConstruct、@PreDestory

JSR-330注解:

@Inject、@Named

 

注解关系

(1) @Autowired =@Resource

(2)@Component=@Repository=@Service=@Controller


-----------------------------------------------------------------------------------------------------------------------------
@Autowired注解:实现自动装配。
1.在 spring xml 配置文件中需要注入如下两个类:

   <beans>
        <bean id="testA" class="..../TestA" />
        <bean id="testUtil" class="..../TestUtil" />
    </beans>

 2.若想要在 testUtil 类中装配 testA 类,则可以在 testUtil 类中使用@Autowired注解;
如果想将 TestA 注入到 TestUtil 中,代码如下:

    public class TestUtil{
        @Autowired
        private Test testA;
        .......
    }

 简单来说,自动装配就是让Spring自动满足bean依赖的一种方法,在满足依赖的过程中,会在Spring应用上下文中寻找匹配某个bean需求的其他bean。
@Autowired注解不仅能够用在构造器上,还能用在方法上,和属性上。如果没有匹配的bean,那么在应用上下文创建的时候,Spring会抛出一个异常。为了避免异常的出现,你可以将@Autowired的required属性设置为false:但是,把required属性设置为false时,你需要谨慎对待。如果在你的代码中没有进行null检查的话,这个处于未装配状态的属性有可能会出现NullPointerException。
@Autowired他是spring特有的注解,如果你不愿意在代码中到处使用Spring的特定注解来完成自动装配任务的话,那么你可以考虑将其替换为@Inject。
在自动装配中,Spring同时支持@Inject(JSR330注解)和@Autowired。尽管@Inject和@Autowired之间有着一些细微的差别,但是在大多数场景下,它们都是可以互相替换的。
注意:1.它只是提供自动装配,并不提供注入;而注入是前提。
            2. 若要实现自动装配还需要导入<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>支持
    或者也可以使用<context:annotation-config />    
    
-----------------------------------------------------------------------------------------------------------------------------

@Qualifier注解:对依赖注入的条件进行限制。
如果@Autowired标注的依赖在容器中只能找到一个实例与之对应,则万事OK,但是如果存在多个同一类型的对象实例,则 @Qualifier 注解将其作用。
假如 Test 类有两个实现,TestA 和 TestB,在 spring 配置文件中配置代码如下:

    <beans>
        <bean id="testA" class="..../TestA" />
        <bean id="testB" class="..../TestB" />
        <bean id="testUtil" class="..../TestUtil" />
    </beans>

 如果想将 TestA 注入到 TestUtil 中,代码如下:

    public class TestUtil{
        @Autowired
        @Qualifier("testA")
        private Test testA;
        private Test testB;
        .......
    }

 

 

-----------------------------------------------------------------------------------------------------------------------------
@Resource注解:实现对 bean 的注入。

@resource 它的作用与@Autowired注解类似。只不过@Autowired按byType 类型自动注入,而@resource默认byName进行自动注入。

@resource有两个重要的属性:name 和 type,故而name可以解析为Bean的名字,从而按照byName进行注入,type可以解析为Bean的类型,从而按照byType进行注入。若没有这两个属性,则使用默认的byName进行自动注入。
1.由于该注解是由JSR250引入的,故而在使用它之前需要导入jsr250相关jar包的支持,在pom.xml文件中加入以下内容:

        <!-- jsr250注解包的引入 -->
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>jsr250-api</artifactId>
            <version>1.0</version>
        </dependency>

 2.在spring配置文件中注入相关类:
    假如 testUtil 类中需要引入 testA 类,在 spring 配置文件中配置代码如下:

    <beans>
        <bean id="testA" class="..../TestA" />
        <bean id="testUtil" class="..../TestUtil" />
    </beans>

 3.在 testUtil 中加入 @Resource(name=“”)注解:
如果想将 TestA 注入到 TestUtil 中,代码如下:

    public class TestUtil{
        @Resource(name=“testA”)
        private Test testA;
        private Test testB;
        .......
    }

 注意:@Resource(name=“”) 中的name 为指定要注入的对象,testA 为 spring 配置文件中所定义 bean 的id。
4.以下两个解释注解的包至少要引入一个到 spring 配置文件,本着偷懒的原则,个人喜欢 context 元素。

<context:annotation-config />    
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

 备注:JSR250注解有 @PostConstruct,@PreDestroy 。
             JSR330注解有 @Inject (代替 @AutoWired)、@Named (代替 @Component)

 

-----------------------------------------------------------------------------------------------------------------------------

@PostConstruct,@PreDestroy注解

spring 容器中的bean是有生命周期的,spring 允许bean 在初始化完成后bean销毁之前执行特定的操作。

你既可以通过实现 InitializingBean/DisposableBean 接口来定制初始化之后/销毁之前的操作方法,也可以通过<bean>元素的 init-method/destory-method 属性来指定初始化之后/销毁之前操作的方法。

jsr-250 指定了@PostConstruct,@PreDestroy这两个注解用于初始化之后/销毁之前方法的指定。

备注:1.这两个注解只能应用与方法之上。

   2.@PostConstruct注解的方法将在类实例化后调用。

   3.@PreDestroy注解的方法将在类销毁之前调用。

 

-----------------------------------------------------------------------------------------------------------------------------

@Component注解:启用组件扫描基础包。

@Resource 与 @Autowired 虽然可以使用自动注入功能,但是还需要在xml配置文件中通过<bean>对 bean 进行定义。也就是说,在xml配置文件中定义bean,通过 @Autowired 或 @Resource 为bean的成员变量、方法或构造器提供自动的注入功能。

那么,能否也通过注释定义 bean ,从xml 配置文件中完全移除 bean 定义的配置呢?答案是肯定的,这就引入了@component注解。

使用:

1.在 spring 配置文件中加入 <context:component-scan>实现自动扫描。
<context:component-scan base-package="com.lh" />
配置完成后,<context:component-scan>会扫描 com.lh 路径下的所有标注了的相应注解的类,并添加到IOC容器中,实现依赖注入。
备注:加入该元素后,就不需要再向 spring 配置文件中注入相关的类,即不需要再使用如下配置:

    <beans>
        <bean id="testA" class="..../TestA" />
        <bean id="testUtil" class="..../TestUtil" />
    </beans>

 2.<context:component-scan> 默认扫描的注解类型是 @Component ,所以需要在相应的类中应用这个注解进行标注。

    
//类A
  @Component
public class TestUtil{ @Autowired private Test testA; ....... } //类B @Component public class TestA{ private int a; private String ss; ... }

 备注:
             (1)该注解是类级别的,它添加在类之上。

  (2)由@Component注解派生出来的注解有@Respository、@Service和@Controller三个,他们所实现的功能与@Component注解完全一样,只是名字看上起更为专业。

@Respository:用来表示DAO类。

@Service:用来标识service类。

@Controller:用来表示控制器类。

-----------------------------------------------------------------------------------------------------------------------------

@Primary注解

在使用@Component注解的时候,有可能根据类型可以匹配到多个符合要求的类。比如注入了实现同一个接口的多个类,此时可以让@Primary注解对spring中类进行特别标识,使它在存在相同类型的时候优先使用该注解下的类。

-----------------------------------------------------------------------------------------------------------------------------

@Value注解

注入基本类型的数据与字符串类型的数据。

 -----------------------------------------------------------------------------------------------------------------------------

自定义注解:

如何自己实现一个自己的注解呢?

我们可以查看源码中关于注解的格式,以@Value注解为例:

@Target({ElementType.FIELD,ElementType.METHOD,ElementTyp.PARAMEHER,ElementTyp.ANNOTION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented

 public @interface Value{
  String value();
}

 其中:

@Target标注了该注解可以使用的地方,如可以使用在属性、方法、参数及注解类型上。

@Retention存在的生命周期。

@Documented是否写入帮助文档中去。

 

////end

posted @ 2016-10-16 20:03  Hosens  阅读(5897)  评论(0编辑  收藏  举报