Spring注解的使用 学习笔记

几乎所有的主流Java框架都打算支持“零配置”特性,都开始支持使用注解来代替XML配置文件。

搜索Bean类

Spring通过使用一些特殊的注解来标注Bean类。Spring提供了如下几个注解来标注Spring Bean:

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

如果需要定义一个普通的Spring Bean,则直接使用@Component标注即可。@Controller、@Service和@Repository能携带更多的语义。

接下来需要在Spring配置文件中指定搜索路径,Spring将会自动搜索该路径下的所有Java类,并根据这些Java类来创建Bean实例。

<!-- 设定业务逻辑层的包扫描器,目的是在指定的路径下,使用@Service注解的类,Spring负责创建对象,并添加依赖 -->
<context:component-scan base-package="com.bnuz.service"/>

上面的代码指定Spring将会把com.bnuz.service包及其子包下的所有Java类都当成Spring Bean来处理,并为每个Java类创建对应的Bean实例。

当然,Spring也允许在使用@Component标注时指定Bean实例的名称,例如如下代码片段:

@Component("axe")
public void Axe(){ }

在默认情况下,Spring会自动搜索所有以@Component、@Controller、@Service和@Repository标注的Java类,并将它们当成Spring Bean来处理。

Spring还提供了@Lookup注解来执行lookup方法注入,其实@Lookup注解的作用完全等同于<lookup-method.../>元素,需要指定name和value元素 

Spring内置了如下4种过滤器
➢ annotation:注解过滤器,该过滤器需要指定一个注解名,如lee.AnnotationTest。
➢ assignable:类名过滤器,该过滤器直接指定一个Java类。
➢ regex:正则表达式过滤器,该过滤器指定一个正则表达式,匹配该正则表达式的Java类将满足该过滤规则,如org\.example\.default.*。
➢ aspectj:AspectJ过滤器,如org.example..*Service+。

此外,还可通过为<component-scan.../>元素添加<include-filter.../><exclude-filter.../>子元素来指定Spring Bean类,其中<include-filter.../>用于强制Spring处理某些Bean类,即使这些类没有使用Spring注解修饰;而<exclude-filter.../>则用于强制将某些Spring注解修饰的类排除在外。 

<context:component-scan base-package="com.bnuz.service">
        <context:include-filter type="regex" expression=".*CHinese"/>
</context:component-scan>

上面配置指定将以Chinese结尾的类配置成容器中的Bean(即使它们没有Spring注解修饰),因此程序中的Chinese结尾的类无须使用@Component注解修饰,Spring也会将它们配置成容器中的Bean。

指定Bean的作用域

当使用XML配置方式来配置Bean实例时,可以通过scope来指定Bean实例的作用域,没有指定scope属性的Bean实例的作用域默认是singleton。

也可以使用@Scope注解,只要在该注解中提供作用域的名称即可。

@Component("axe")
@Scope("prototype")
public void Axe(){ }

此外,Spring 4.3还新增了@ApplicationScope、@SessionScope、@RequestScope这三个注解,它们分别对应于@Scope("application")、@Scope("session")、@Scope("request"),且proxyMode属性被设为ScopedProxyMode.TARGET_CLASS。

使用@Resource、@Value配置依赖

通过使用@Resource注解为目标Bean指定合作者Bean,与XML中<property.../>元素的ref属性有相同的效果,@Value则相当于<property.../>元素的value属性,用于为Bean的标量属性配置属性值。

当使用@Resource标注setName()方法,Spring默认会注入容器中名为name的组件;当使用@Resource标注name实例变量,Spring默认会注入容器中名为name的组件。

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

@PostConstruct指定Bean的初始化方法——Spring容器将会在Bean的依赖关系注入完成后回调该方法。
@PreDestroy指定Bean销毁之前的方法——Spring容器将会在销毁该Bean之前回调该方法。

两者不需要指定任何属性。

@DependsOn和@Lazy

@DependsOn用于强制初始化其他Bean;而@Lazy则用于指定该Bean是否取消预初始化。

@DependsOn可以修饰Bean类或方法,在使用该注解时可以指定一个字符串数组作为参数,每个数组元素对应于一个强制初始化的Bean。 

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

@Autowired自动装配和精确装配

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

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

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

@Autowired还可用于标注集合类型的实例变量,或标注形参类型的集合方法,对于这种集合类型的参数而言,程序中必须使用泛型。

当出现有多个匹配类型的候选组件,此时就会导致异常。因此Spring提供了一个@Primary注解,该注解用于将指定候选Bean设置为主候选者Bean。

Spring 4及以上版本增强后的@Autowired注解还可以根据泛型进行自动装配。 

为了实现精确的自动装配,Spring提供了@Qualifier注解,使用该注解允许根据Bean的id来执行自动装配。 

Spring 5新增的注解

@NonNull:该注解主要用于修饰参数、返回值和Field,声明它们不允许为null。
@NonNullApi:该注解用于修饰包,表明该包内API的参数、返回值都不应该为null。如果希望该包内某些参数、返回值可以为null,则需要使用@Nullable修饰它们。
@NonNullFields:该注解也用于修饰包,表明该包内的Field都不应该为null。如果希望该包内的某些Field可以为null,则需要使用@Nullable修饰它们。

从上面的介绍不难看出,这三个注解的功能基本相似,区别只是作用范围不同:@NonNull每次只能影响被修饰的参数、返回值和Field;而@NonNullApi、@NonNullFields则会对整个包起作用,其中@NonNullApi的作用范围是包内的所有参数+返回值,@NonNullFields的作用范围是包内的所有Field。 

配置第三方Bean

导入第三方jar包后如果需要用到里面某些组件,可以用@Bean注解修饰返回该组件的方法,如下是返回Mybatis Plus的拦截器的Bean:

@Component
public class MPConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }

}

@Import和@ImportResource

 @ImportResource可以为自定义容器类导入配置文件:

@ImportResource("applicationContext.xml")
public class XXXXConfig {... }

@import可以在自定义容器类上指定你要导入的类:

@Import({Person.class})
public class XXXXConfig {... }

该Person类无需用使用@Component注解。

其他

@ConditionalOn...注解为bean的加载设置条件:

@ConditionalOnClass:

@ConditionalOnClass(Person.class)//判断有Person这个类

@ConditionalOnMissingClass:

@ConditionalOnMissingClass("com.bnuz.person")//通过全路劲类名判断没有person这个类

@ConditionalOnBean:

@ConditionalOnBean(name="com.bnuz.person")//判断有这个Bean

@ComponentScan:该注解指定扫描指定包及其子包下所有的配置类或 Bean组件。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值