Spring中重要的一些注解及其实现原理

1.启动类@SpringBootApplication注解:

@SpringBootApplication
public class StartEurekaApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(StartEurekaApplication.class, args);
    }
}

对于@SpringBootApplication注解,它其实是一个组合型注解,它是由以下几个注解所组成的:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
      @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
      @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}

这个注解的主要作用是声明让spring boot自动给程序进行必要的配置,这个配置等同于@Configuration ,@EnableAutoConfiguration 和 @ComponentScan 三个注解,以上其他注解都是spring的元注解,在此就不做说明。

2.@Configuration注解:

相当于传统的xml配置文件,如果有些第三方库需要用到xml文件,建议仍然通过@Configuration类作为项目的配置主类——可以使用@ImportResource注解加载xml配置文件。

3.@EnableAutoConfiguration注解:

SpringBoot自动配置(auto-configuration):尝试根据你添加的jar依赖自动配置你的Spring应用。例如,如果你的classpath下存在HSQLDB,并且你没有手动配置任何数据库连接beans,那么我们将自动配置一个内存型(in-memory)数据库”。你可以将@EnableAutoConfiguration或者@SpringBootApplication注解添加到一个@Configuration类上来选择自动配置。如果发现应用了你不想要的特定自动配置类,你可以使用@EnableAutoConfiguration注解的排除属性来禁用它们。
当spring boot扫描到@EnableAutoConfiguration注解时则会将spring-boot-autoconfigure.jar/META-INF/spring.factories文件中org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的value里的所有xxxConfiguration类加载到IOC容器中。而xxxAutoConfiguration类一般都会有@ConditionalOnxxx注解,通过这些条件注解来判断是否真正的创建xxxConfiguration对象。spring boot的各种spring-boot-starter-xxx.jar也正是居于此注解来达到自动装配的目的。

4.@ComponentScan注解:

主要用途是自动发现扫描组件。相当于,如果扫描到有@Component、@Controller、@Service等这些注解的类,并注册为Bean,可以自动收集所有的Spring组件,包括@Configuration类。我们经常使用@ComponentScan注解搜索beans,并结合@Autowired注解导入。可以自动收集所有的Spring组件,包括@Configuration类。我们经常使用@ComponentScan注解搜索beans,并结合@Autowired注解导入。如果没有配置的话,Spring Boot会扫描启动类所在包下以及子包下的使用了@Service,@Repository等注解的类。

5.@ResponseBody注解:

作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。注意:在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。@ResponseBody是作用在方法上的,@ResponseBody 表示该方法的返回结果直接写入 HTTP response body 中,一般在异步获取数据时使用【也就是AJAX】,用于构建Restful风格的api。
注意:在使用 @RequestMapping后,返回值通常解析为跳转路径,但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中。 比如异步获取 json 数据,加上 @ResponseBody 后,会直接返回 json 数据。@RequestBody 将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。

6.@Controller注解:

用于定义控制器类,在spring项目中由控制器负责将用户发来的URL请求转发到对应的服务接口(service层),一般这个注解在类中,通常方法需要配合注解@RequestMapping。

7.@RestController注解:

也是同于定义控制器类,这个注解相当于@ResponseBody和@Controller的组合。

8.@RequestMapping注解:

用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
这个注解有以下六个属性
a.value:指定请求的实际地址,指定的地址可以是URI Template 模式。
b.method:指定请求的method类型, GET、POST、PUT、DELETE等。
c.consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html。
d.produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回。
e.params: 指定request中必须包含某些参数值是,才让该方法处理。
f.headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。

9.@Autowired注解:

它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Autowired的使用来消除 set ,get方法。

10.@Service注解:

用于标注业务逻辑层服务,主要用来进行业务的逻辑处理,注入DAO。这种bean默认是单例的,如果想改变,可以使用@Service(“beanName”) 、@Scope(“prototype”)来改变。

11.@Repository注解:

数据持久层,该注解修饰哪个类,则表明这个类具有对数据库进行CRUD(增删改查)的功能,而且@Repository是@Component注解的一个派生品,所以被@Repository注解的类可以自动的被@ComponentScan 通过路径扫描给找到。

12.@Component注解:

将一个类标识为组件,泛指各种组件,就是说当我们的类不属于各种归类的时候(不属于@Controller、@Services等的时候),我们就可以使用@Component来标注这个类。

13.@Bean注解:

Spring的@Bean注解用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中。SpringIOC 容器管理一个或者多个bean,这些bean都需要在@Configuration注解下进行创建,在一个方法上使用@Bean注解就表明这个方法需要交给Spring进行管理。

14.@Entity注解:

使用该注解表明该类 (UserEntity) 为一个实体类,它默认对应数据库中的表名是user_entity。这里也可以写成@Entity(name = “xxx”)。

15.@Id注解:

用在某个属性上表示该属性为主键,一般出现在实体类中。

16.@Transactional注解:

一般情况下我们在处理具体的业务都是在Service层来进行处理操作,此时如果在Service类上添加@Transactional注解的话,那么Service曾的每一个业务方法调用的时候都会打开一个事务。Spring默认情况下会对(RuntimeException)及其子类来进行回滚,在遇见Exception及其子类的时候则不会进行回滚操作。 @Transactional既可以作用于接口,接口方法上以及类已经类的方法上。但是Spring官方不建议接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。 Spring默认使用的是jdk自带的基于接口的代理,而没有使用基于类的代理CGLIB。@Transactional注解底层使用的是动态代理来进行实现的,如果在调用本类中的方法,此时不添加@Transactional注解,而是在调用类中使用thisi调用本类中的另外一个添加了@Transactional注解,此时this调用的方法上的@Transactional注解是不起作用的。
这个注解有几个事务传播属性如下:

@Transactional(propagation=Propagation.REQUIRED)//如果有事务,那么加入事务,没有的话新创建一个
@Transactional(propagation=Propagation.NOT_SUPPORTED)//这个方法不开启事务
@Transactional(propagation=Propagation.REQUIREDS_NEW)//不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
@Transactional(propagation=Propagation.MANDATORY)//必须在一个已有的事务中执行,否则抛出异常
@Transactional(propagation=Propagation.NEVER)//不能在一个事务中执行,就是当前必须没有事务,否则抛出异常
@Transactional(propagation=Propagation.SUPPORTS)//其他bean调用这个方法,如果在其他bean中声明了事务,就是用事务。没有声明,就不用事务。
@Transactional(propagation=Propagation.NESTED)//如果一个活动的事务存在,则运行在一个嵌套的事务中,如果没有活动的事务,则按照REQUIRED属性执行,它使用一个单独的事务。这个书屋拥有多个回滚的保存点,内部事务的回滚不会对外部事务造成影响,它只对DataSource TransactionManager事务管理器起效。
@Transactional(propagation=Propagation.REQUIRED,readOnly=true)//只读,不能更新,删除
@Transactional(propagation=Propagation.REQUIRED,timeout=30)//超时30秒

17.@Mapper注解:

@Mapper同样使用于数据持久层,属于mybatis的一个注解,可以把mapper这个DAO交給Spring管理,使用之后不用再写mapper映射文件,使用该注解的接口可以自动生成一个实现类。

18.@MapperScan注解:

由于@Mapper针对的是一个一个的接口,使用起来其实不太方便,所以产生了@MapperScan注解,它可以配置一个或多个包路径,自动的扫描这些包路径下的类,自动的为它们生成代理类,一般在启动类上使用。

19.Lombok插件注解:

由于我特别喜欢这个插件,而且它也可以为我们编写代码省很多功夫,所以我也把它列举在这,它最常用的几个注解如下:
A.@Data:注解在类上;提供类所有属性的 getting 和 setting 方法,此外还提供了equals、canEqual、hashCode、toString 方法
B.@Setter:注解在属性上;为属性提供 setting 方法
C.@Getter:注解在属性上;为属性提供 getting 方法
D.@NoArgsConstructor:注解在类上;为类提供一个无参的构造方法
E.@AllArgsConstructor:注解在类上;为类提供一个全参的构造方法