Spring和SpringBoot的常用注解
引入
传统的Spring做法是使用 xml 文件来对 bean 进行注入或者是配置切面、事物,这么做有两个主要的问题:
1、如果所有的内容都配置在 xml 文件中,那么 xml 文件将会十分庞大;如果按需求分开 xml 文件,那么 xml 文件又会非常多。总之这将导致配置文件的可读性与可维护性变得很低。
2、在开发中在 java 文件和 xml 文件之间不断切换,是一件麻烦的事,同时这种思维上的不连贯也会降低开发的效率。
为了解决这两个问题,Spring 引入了注解机制,通过”@XXX”的方式,让注解与 java bean 紧密结合,既大大减少了配置文件的体积,又增加了java bean的可读性与内聚性。
Spring 常用注解
@Autowired
@Autowired 顾名思义,就是自动装配,其作用是为了消除代码 Java 代码里面的 getter/setter 与 bean 属性中的 property 。当然,getter 看个人需求,如果私有属性需要对外提供的话,应当予以保留。
@Autowired 默认按类型匹配的方式,在容器查找匹配的 bean,当有且仅有一个匹配的 bean时,Spring将其注入 @Autowired 标注的变量中。
@Autowired 注解的 required 属性设置为 false 时,即使没有找到 bean 也不会报错。
@Qualifier(指定注入Bean的名称)
如果容器中有一个以上匹配的Bean,则可以通过 @Qualifier 注解限定 bean的名称,通常和 @Autowired 组合使用。
@Resource
@Resource注解与@Autowired注解作用非常相似,但是它默认是 byname 的,也就是按名称装配。
- @Resource后面没有任何内容,默认通过 name 属性去匹配 bean,找不到再按 type 去匹配
- 指定了 name 或者 type 则根据指定的类型去匹配 bean
- 指定了 name 和 type 则根据指定的 name 和 type 去匹配 bean,任何一个不匹配都将报错
@Autowired 和 @Resource 两个注解的区别
@Autowired 默认按照 byType 方式进行 bean 匹配,@Resource 默认按照 byName 方式进行 bean 匹配
@Autowired 是 Spring 的注解,@Resource 是 J2EE 的注解,这个看一下导入注解的时候这两个注解的包名就一清二楚了
Spring 属于第三方的,J2EE 是 Java 自己的东西。因此,建议使用 @Resource 注解,以减少代码和 Spring 之间的耦合。
@Component
@Component 是所有受 Spring 管理组件的通用形式,@Component 注解可以放在类的头上,@Component 不推荐使用,更加推荐按照类的职责来将其标注为下面三个注解。
@Repository
@Repository 对应数据访问层组件,也就是 DAO 层的 bean,作用等同于 @Component 。
@Service
@Service 用于标注业务层组件,也就是 Service 层的 bean,作用等同于 @Component 。
@Controller
@Controller 对应控制层组件,也就是 Controller 层的 bean,作用等同于 @Component 。
@Component、@Repository、@Service 和 @Controller
它们的作用都是把普通 pojo 实例化到 spring 容器中,相当于配置文件中的<bean id="" class=""/>,它们如果没有指定 value 属性时,则默认的 bean 名字为这个类的类名首字母小写。如果指定了,就会以指定的 value 作为名字。
@ResponseBody
@ResponseBody 的作用其实是将 java 对象转为 json 格式的数据。
@responseBody 注解的作用是将 controller 的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到 response 对象的 body 区,通常用来返回 JSON 数据或者是 XML 数据。
@RequestMapping
在 Controller 层中使用 @RequestMapping 来映射请求,也就是通过它来指定控制器可以处理哪些URL请求。
该注解有六个属性:
params:指定request中必须包含某些参数值是,才让该方法处理。
headers:指定request中必须包含某些指定的header值,才能让该方法处理请求。
value:指定请求的实际地址,指定的地址可以是URI Template 模式
method:指定请求的method类型, GET、POST、PUT、DELETE等
consumes:指定处理请求的提交内容类型(Content-Type),如application/json,text/html;
produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
@RequestParam
用于将请求参数区数据映射到功能处理方法的参数上,value 属性就是要接收从接口传递过来的参数的值的,如果接口传递过来的参数名和你接收的不一致,可以自己指定value。
在下面例子中,前台传递过来的参数名和后台接收的参数名相同,所以无需指定 value 属性。
后台:
前台:
@Scope
用来配置 spring bean 的作用域,它标识 bean 的作用域。
默认值是单例
1、singleton:单例模式,全局有且仅有一个实例
2、prototype:原型模式,每次获取Bean的时候会有一个新的实例
3、request:request 表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效
4、session:session 作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效
@Configuration
从Spring3.0,**@Configuration用于定义配置类,相当于XML中的<beans>< /beans>。一般加在主类上,被注解的类内部包含有一个或多个被 @Bean 注解的方法,这些方法将会被 **AnnotationConfigApplicationContext 或 AnnotationConfigWebApplicationContext 类进行扫描,并用于构建bean定义,初始化 Spring 容器。
@ComponentScan
组件扫描。相当于<context:component-scan />,如果扫描到有@Component @Controller @Service等这些注解的类,则把
这些类注册为bean。
@Bean
相当于XML中的<bean>< /bean>,放在方法的上面,而不是类,意思是产生一个bean,并交给spring管理。
@Transactional
通过这个注解可以声明事务,可以添加在类上或者方法上。
@PathVariable
路径变量注解,@RequestMapping中用{}来定义url部分的变量名
SpringBoot常用注解
在 SpringBoot 中,摒弃了spring以往项目中大量繁琐的配置,遵循约定大于配置的原则,通过自身默认配置,极大的降低了项目搭建的复杂度。同样在 SpringBoot 中,大量注解的使用,使得代码看起来更加简洁,提高开发的效率。这些注解不光包括 SpringBoot 自有,也有一些是继承自 Spring 的,笔者对一些已经在 spring 中出现过的部分注解不予说明了。
@SpringBootApplication
查看源码可发现,@SpringBootApplication 是一个复合注解,包含了@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan这三个注解。
这三个注解的作用分别为:
- @SpringBootConfiguration:标注当前类是配置类,这个注解继承自@Configuration。并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到 spring 容器中,并且实例名就是方法名。
- @EnableAutoConfiguration:是自动配置的注解,这个注解会根据我们添加的组件jar来完成一些默认配置,我们做微服务时会添加spring-boot-starter-web 这个组件 jar 的 pom 依赖,这样配置会默认配置 springmvc 和 tomcat。
- @ComponentScan:扫描当前包及其子包下被@Component,@Controller,@Service,@Repository注解标记的类并纳入到spring 容器中进行管理。等价于
<context:component-scan />的 xml 配置文件中的配置项。
大多数情况下,这3个注解会被同时使用,基于最佳实践,这三个注解就被做了包装,成为了 @SpringBootApplication 注解。
@ServletComponentScan
在 SpringBootApplication 上使用 @ServletComponentScan 注解后,Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener 注解自动注册,无需其他代码。
@MapperScan
SpringBoot 支持 mybatis 组件的一个注解,通过此注解指定 mybatis 接口类的路径,即可完成对 mybatis 接口的扫描。
它和 @mapper 注解是一样的作用,不同的地方是扫描入口不一样。@mapper 需要加在每一个 mapper 接口类上面。所以大多数情况下,都是在规划好工程目录之后,通过 @MapperScan 注解配置路径完成 mapper 接口的注入。
在 pom.xml 中添加 mybatis 相应组建依赖之后,就可以使用该注解。
资源导入注解
@ImportResource @Import @PropertySource 这三个注解都是用来导入自定义的一些配置文件。
@ImportResource(locations={}) 导入其他 xml 配置文件,需要标准在主配置类上。
@PropertySource 导入property的配置文件,value 属性指定文件路径,这个相当于使用spring的
<import resource />标签来完成配置项的引入。@import 注解是可以将普通类导入到 spring 容器中做管理
@Component
是通用注解,其他三个注解是这个注解的拓展,并且具有了特定的功能。
通过这些注解的分层管理,就能将请求处理,义务逻辑处理,数据库操作处理分离出来,为代码解耦,也方便了以后项目的维护和开发。
所以我们在正常开发中,如果能用@Service, @Controller, @Repository 其中一个标注这个类的定位的时候,就不要用 @Component 来标注。
@Repository
@Repository 注解类作为 DAO 对象,管理操作数据库的对象。
总得来看,@Component, @Service, @Controller, @Repository 是 spring 注解,注解后可以被 spring 框架所扫描并注入到 spring 容器来进行管理。
@Service
这个注解用来标记业务层的组件,我们会将业务逻辑处理的类都会加上这个注解交给 spring 容器。事务的切面也会配置在这一层。当然这个注解不是一定要用。有个泛指组件的注解 @Component ,当我们不能确定具体作用的时候就可以用泛指组件的注解托付给 spring 容器。
@Controller
表明这个类是一个控制器类,和 @RequestMapping 来配合使用拦截请求,如果不在 method 中注明请求的方式,默认是拦截 get 和 post 请求。这样请求会完成后转向一个视图解析器。但是在大多微服务搭建的时候,前后端会做分离。所以请求后端只关注数据处理,后端返回 json 数据的话,需要配合 @ResponseBody 注解来完成。
这样一个只需要返回数据的接口就需要3个注解来完成,大多情况我们都是需要返回数据。也是基于最佳实践,所以将这三个注解进一步整合变成下面的 @RestController 注解。
@RestController
它是 @Controller 和 @ResponseBody 的结合,一个类被加上 @RestController 注解,数据接口中就不再需要添加 @ResponseBody。更加简洁。
@RequestMapping
同 @RestController 的问题一样,每次使用@RequestMapping(value=””,method= RequestMethod.GET )时,我们都需要明确请求方式。这样的写法又会显得比较繁琐,于是乎就有了如下的几个注解。
| 普通风格 | Rest风格 |
|---|---|
| @RequestMapping(value=“”,method = RequestMethod.GET) | @GetMapping(value =“”) |
| @RequestMapping(value=“”,method = RequestMethod.POST) | @PostMapping(value =“”) |
| @RequestMapping(value=“”,method = RequestMethod.PUT) | @PutMapping(value =“”) |
| @RequestMapping(value=“”,method = RequestMethod.DELETE) | @DeleteMapping(value =“”) |
这几个注解是 @RequestMapping(value=””,method= RequestMethod.xxx )的最佳实践。为了代码的更加简洁。
@CrossOrigin
@CrossOrigin(origins = “”, maxAge = 1000) 这个注解主要是为了解决跨域访问的问题。这个注解可以为整个 controller 配置启用跨域,也可以在方法级别启用。
我们在项目中使用这个注解是为了解决微服务在做定时任务调度编排的时候,会访问不同的 spider 节点而出现跨域问题。
@Transactional
在spring boot中不用再单独配置事务管理,一般情况是我们会在 servcie 层添加了事务注解,即可开启事务。要注意的是,事务的开启只能在 public 方法上,并且主要事务切面的回滚条件。正常我们配置 rollbackfor exception 时 ,如果在方法里捕获了异常就会导致事务切面配置的失效。










