【Spring学习】Annotation-Driven(注解驱动编程)-spring、java常用注解

Spring2.5为我们引入了组件自动扫描机制(Annotation),它可以在类路径下寻找标记了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入到spring容器中管理,它的作用和在xml中使用bean节点配置组件一样。

1,@SpringBootApplication

通常用在主类上,是@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三个注解的复合注解。

注解场景说明备注
@SpringBootConfiguration配置类注解,相当于等同于@Configuration
@EnableAutoConfiguration开启自动配置类,激活spring的自动装配机制
@ComponentScan激活@Component扫描通过basePackages可指定扫描路径,默认从声明@ComponentScan所在类的package进行扫描
@Configuration(“name”)声明当前类为配置类;通过@Resource(name = "restTemplateHttps")引入不同的类name可缺省
@Bean注解在方法上,声明当前方法的返回值为一个bean,替代xml中的方式;Spring只调用一次产生这个Bean对象的方法,随后Spring将这个Bean对象放在自己的IOC容器中进行管理。这些bean并不一定要在@Configuration注解下进行创建,在@Component注解下也一样可以。
@OrderIOC容器中Bean的执行顺序的优先级;
默认是最低优先级,值越小优先级越高
Bean的加载顺序不受@Order或Ordered接口的影响;
主要用于相互依赖的对象的执行
@EnableConfigurationProperties开启对@ConfigurationProperties注解配置Bean的支持;
@EnableJpaRepositories开启对SpringData JPA Repository的支持;

2)@EnableAutoConfiguration原理

@Import+@Configuration+Spring SPI

Spring SPI(Service Provider Interface):JDK1.6
是Java提供的一套用来被第三方实现或者扩展的接口,它可以用来启用框架扩展和替换组件。
SPI是调用方来制定接口规范,提供给外部来实现,调用方在调用时则选择自己需要的外部实现。

@EnableAutoConfiguration是一个复合注解:

  1. @AutoConfigurationPackage:注册扫描路径。
    即:@Import(AutoConfigurationPackages.Registrar.class),Registrar重写了ImportBeanDefinitionRegistrar,在启动时扫描主启动类包和子包下的所有组件并加载到 Spring 容器。
  2. @Import(AutoConfigurationImportSelector.class):实现自动装配。
    AutoConfigurationImportSelector中的方法public String[] selectImports(AnnotationMetadata annotationMetadata),返回类的全路径并加载到IOC容器中,spring再将全路径通过反射(SpringFactoriesLoader.loadFactoryNames)作为bean放入IOC容器中。
    ==>举例:mybatis的引用:mybatis将@Configuration和@Bean的全限定名放入META-INF/spring.factories的jar包(存放了所有bean的全路径,以key-value形式存储)。项目引入mybatis依赖后,从spring.factories扫描类的全路径,通过反射将所有的bean放入IOC容器。

2,依赖注入相关注解

3,Spring MVC Annotation

4,参数校验

5,JSON相关注解

6,切面(AOP)注解

7,@Value

(1)支持如下方式的注入:

  1. 注入普通字符
  2. 注入操作系统属性
  3. 注入表达式结果
  4. 注入其它bean属性
  5. 注入文件资源
  6. 注入网站资源
  7. 注入配置文件

(2)@Value三种情况的用法。

  1. ${}是去找外部配置的参数,将值赋过来
    ${} 可以出现在java类配置或XML文件中,Spring会从各种已经配置了的来源中解析属性。
    要添加属性来源,可以在@Configuration类上增加@PropertySource注解,如:
@Configuration
@PropertySource("classpath:/META-INF/resources/app.properties")
public class Config{……}
  1. #{}是SpEL表达式,去寻找对应变量的内容
  2. #{}直接写字符串就是将字符串的值注入进去

8,环境切换

注解场景说明备注
@Profile指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件。
@Conditional通过实现Condition接口,并重写matches方法,从而决定该bean是否被实例化。

9,任务执行&调度:@Async和@Scheduled

11,测试相关注解

12,lombok相关注解

13,缓存相关

Spring 从 3.1 开始就引入了对 Cache 的支持。定义了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 接口来统一不同的缓存技术。并支持使用 JCache(JSR-107)注解简化我们的开发。

注解说明备注
@EnableCaching开启注解式的缓存支持;用于主启动类
@Cacheable将运行结果缓存,以后查询相同的数据,直接从缓存中取,不需要调用方法。作用于方法

@Cacheable常用属性:

属性说明备注
acheNames/value用来指定缓存组件的名字
key缓存数据时使用的 key,可以用它来指定。默认是使用方法参数的值。(这个 key 你可以使用 spEL 表达式来编写)
keyGeneratorkey 的生成器。 key 和 keyGenerator 二选一使用
cacheManager可以用来指定缓存管理器。从哪个缓存管理器里面获取缓存。
condition可以用来指定符合条件的情况下才缓存
unless否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。当然你也可以获取到结果进行判断。(通过 #result 获取方法结果)unless = "#result.getData() == null"表示null不缓存
sync是否使用异步模式。

14,java注解(Java标注、元数据)

jdk5引入,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。

注解说明作用域
@Override表示重写,如果无法重写会编译报错注解后编译器就进行检查
@SuppressWarnings选择性地取消特定代码段(即,类或方法)中的警告。注解后编译器就进行检查
@Deprecated用来注解类、接口、成员方法和成员变量等,用于表示某个元素(类、方法等)已过时。当其他程序使用已过时的元素时,编译器将会给出警告。注解后编译器就进行检查
@FunctionalInterface指示被修饰的接口是函数式接口,在 JDK8 引入

1)@SuppressWarnings

Suppress 抑制;镇压;废止 Warnings警告

@SuppressWarnings(“resource”)是J2SE 提供的一个批注。该批注的作用是给编译器一条指令,告诉它对被批注的代码元素内部的某些警告保持静默。

@SuppressWarnings 批注允许您选择性地取消特定代码段(即,类或方法)中的警告。其中的想法是当您看到警告时,您将调查它,如果您确定它不是问题,您就可以添加一个 @SuppressWarnings 批注,以使您不会再看到警告。
虽然它听起来似乎会屏蔽潜在的错误,但实际上它将提高代码安全性,因为它将防止您对警告无动于衷 — 您看到的每一个警告都将值得注意。

常见参数说明:

参数作用
deprecation使用了不赞成使用的类或方法时的警告
unchecked执行了未检查的转换时的警告,例如: 当使用集合时没有用泛型来指定集合保存的类型。
fallthrough当switch程序块直接通往下一种情况没有break时警告;
path再类路径、源文件路径等种有不存在的路径时的警告
serial当再可序列号的类上缺少serialVerisonUID定义时的警告
finally任何finally子句不能正常完成时的警告
all所有的警告

2)函数式接口(Functional Interface)

函数式接口就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。

@FunctionalInterface
public interface UserService {
    void getUser(Long userId);

    // 默认方法,可以用多个默认方法
    public default void setUser() {
    }
    // 静态方法
    public static void saveUser() {
    }
    
    // 覆盖Object中的equals方法
    public boolean equals(Object obj);
}

15,数据库相关注解

注解说明作用域
@schema标注在class上,表示此类对应的数据库表对应的schema。

1)@Schema

可以用如下语句判断某个实体类上是否带有@schema注解,从而得到schema。

bean.getClass().isAnnotationPresent(Schema.class)

16,执行顺序相关的注解

从Java EE5规范开始,Servlet中增加了两个影响Servlet生命周期的注解,@PostConstruct和@PreDestroy,这两个注解被用来修饰一个非静态的void()方法。

1)@PostConstruct

注解后方法执行时间:在依赖注入完成后被自动调用。
服务器加载serlvet >> Constructor >> @Autowired >> @PostConstruct

@PostConstruct
 
public void someMethod(){}

1>场景

可作为一些数据的常规化加载,比如数据字典之类的。
或者打印一些启动时加载的配置的log。

2)@PreDestroy

执行顺序:destroy >>@PreDestroy>>服务器卸载serlvet

17,处理异常

注解说明
@ControllerAdvice包含@Component,可以被扫描,用于统一处理异常
@ExceptionHandler(Exception.class)用于方法上表示遇到这个异常就执行这个方法,与@ControllerAdvice 配合使用

18,Java Doc

sun公司提供的一个源代码配套的API注解文档。

常用标签说明标签作用域
@author 作者作者标识包、 类、接口
@version 版本号版本号包、 类、接口
@param 参数名 描述方法的入参名及描述信息方法
@return 描述函数返回值方法
@deprecated 过期文本标识随着程序版本的提升,当前API已经过期,仅为了保证兼容性依然存在,以此告之开发者不应再用这个API。包、类、接口、值域、构造函数、 方法
@throws异常类名构造函数或方法所会抛出的异常方法
@exception 异常类名同@throws。
@see #[method或field]查看相关内容,如类、方法、变量等。包、类、接口、值域、构造函数、 方法
@since 描述文本API在什么程序的什么版本后开发支持。包、类、接口、值域、构造函数、 方法
{@link #[method或field]}链接到某个特定的成员对应的文档中包、类、接口、值域、构造函数、 方法
{@value}当对常量进行注释时,如果想将其值包含在文档中,则通过该标签来引用常量的值。静态值域

19,自定义注解

1)概念

注解可以看作是一种特殊的标记,可以用在方法、类、参数和包上,程序在编译或者运行时可以检测到这些标记而进行一些特殊的处理,例如标注在方法上可以实现接口权限的校验。

2)场景

自定义注解+拦截器或者 AOP。

3)语法(元注解)

元注解:定义其他注解的注解。

//通过关键字 @interface 声明为注解
public @interface SystemConfig {
    
}

注解的元素类型主要有@Target,@Retention,@Document,@Inherited 用来修饰注解。

1>@Target

表明该注解可以应用的java元素类型。

Target类型描述
ElementType.TYPE应用于类、接口(包括注解类型)、枚举
ElementType.FIELD应用于属性(包括枚举中的常量)
ElementType.METHOD应用于方法
ElementType.PARAMETER应用于方法的形参
ElementType.CONSTRUCTOR应用于构造函数
ElementType.LOCAL_VARIABLE应用于局部变量
ElementType.ANNOTATION_TYPE应用于注解类型
ElementType.PACKAGE应用于包
ElementType.TYPE_PARAMETER1.8版本新增,应用于类型变量)
ElementType.TYPE_USE1.8版本新增,应用于任何使用类型的语句中(例如声明语句、泛型和强制转换语句中的类型)

2>@Retention

表明该注解的生命周期。

生命周期类型描述
RetentionPolicy.SOURCE编译时被丢弃,不包含在类文件中
RetentionPolicy.CLASSJVM加载时被丢弃,包含在类文件中,默认值
RetentionPolicy.RUNTIME由JVM 加载,包含在类文件中,在运行时可以被获取到

3>@Documented

表明该注解标记的元素可以被Javadoc 或类似的工具文档化。

4>@Inherited

表明使用了@Inherited注解的注解,所标记的类的子类也会拥有这个注解@Target,@Retention,@Document,@Inherited

4)demo

//该注解可以应用于类、接口(包括注解类型)、枚举
@Target(ElementType.TYPE)
//该注解标记的元素可以被Javadoc 或类似的工具文档化
@Documented
//该注解的生命周期,由JVM 加载,包含在类文件中,在运行时可以被获取到
@Retention(RetentionPolicy.RUNTIME)
public @interface SystemConfig {
    String name() default "lin";
    int age();
}

//应用SystemConfig注解到User类
@SystemConfig(age = 20)
public class User {
    private String name;

    private Integer age;
}

public class AnnotationTest {

    public static void main(String[] args) {
        //获取User的Class对象
        Class<?> userClass = User.class;
        //判断Class对象上是否有SystemConfig的注解
        if (userClass.isAnnotationPresent(SystemConfig.class)) {
            System.out.println("User上配置了SystemConfig注解");
            //获取SystemConfig注解
            SystemConfig config = userClass.getAnnotation(SystemConfig.class);
            System.out.println("SystemConfig.name:" + config.name() + "; SystemConfig.age:" + config.age());
        } else {
            System.out.println("User上没有配置SystemConfig注解");
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值