前言:在使用Spring家族的过程中,使用到了各种各样的注解,本人将使用过程中出现的大部分注解做了一个汇总,方便回顾
目录
1.@Component/@Controller/@Service/@Repository:标识组件的常用注解
4.@before/@After/@AfterReturning/@AfterThrowing/@Around:标注AOP的通知方法注解
10.@GetMapping/@PostMapping/@DeleteMapping/@PutMapping:处理不同请求的注解
11.@PathVariable:绑定路径中的占位符与形参的注解
14.@RestController:相当于@ResponseBody + @Controller
15.@Configuration + @Bean:一起使用代替xml配置文件的注解
20.lombok自带注解:@Data、@ToString、@AllArgsConstructor、@NoArgsContructor、@Slf4j
1.@Component/@Controller/@Service/@Repository:标识组件的常用注解
1.标注位置:标注在类上(若为接口则不能标注,只能标注在接口的实现类上)
2.功能:
* @Component:将类标识为普通组件
* @Controller:将类标识为控制层组件,处理用户请求
* @Service:将类标识为业务层组件
* @Repository:将类标识为持久层组件,操作数据库
2.@Autowired:实现自动装配功能的注解
1. 功能
实现自动装配功能的注解
2. 能够标识的位置
- 标识在成员变量上,此时不需要设置成员变量的set方法(一般用这个,此时可以不用在创造set方法)
- 标识在set方法上
- 标识在为当前成员变量赋值的有参构造器上
3. 原理
- 默认通过byType方式,在ioc容器中通过类型匹配某个bean为属性赋值(一般都是这个就可以)
- 若有多个类型匹配的bean,此时会自动转换为byName的方式实现自动装配的效果;即将要赋值的属性的属性名作为bean的id匹配某个bean为属性赋值
- 若byType和byName的方式都无法实现自动装配,即IOC容器中有多个类型匹配的bean,且这些bean的id和要赋值的属性的属性名都不一致,此时会抛出异常:NoUniqueBeanDefinitionException(这种情况几乎不会发生,一般默认byType就能处理,因为一个类型的bean不会在ioc容器中存在多个)
- 此时可以在要赋值的属性上,添加一个注解@Qualifier;通过该注解的value属性值,指定某个bean的ID,将这个bean为属性赋值
3.@Qualifier:限定某个bean的注解
创建了多个相同类型的bean,但仅装配其中一个bean时,则使用@Qualifier 和 @Autowired配合,来指定一个确定的bean。
代码示例:比如Person接口,有两个实现类:PersonImpl1和PersonImpl2;则进行自动装配时
@Autowired
@Qualifier(value = "PersonImpl1")
private Person person;
4.@before/@After/@AfterReturning/@AfterThrowing/@Around:标注AOP的通知方法注解
1.注解功能:
1. @before:前置通知,在目标对象方法执行之前执行
2. @After:后置通知,在目标对象方法的finally字句中执行
3. @AfterReturning:返回通知,在目标对象方法返回值之后执行
4. @AfterThrowing:异常通知,在目标对象方法的catch字句中执行
5. @Around:环绕通知,将所有通知都实现的通知(在实际中,要么使用环绕通知全部实现通知方法,要么只在特定位置写上通知)
2.代码示例:
@Component
@Aspect //将当前组件标识为切面
public class LoggerAspect {
//可重用的切入点表达式
@Pointcut("execution(* com.gz.spring.annotation.CalculatorImpl.*(..))")
//切入点表达式:execution(* com.gz.spring.annotation.CalculatorImpl.*(..))
public void pointCut(){
}
//1.前置通知
@Before("pointCut()")
public void beforeAdviceMethod(JoinPoint joinPoint){
//获取连接点所对应方法的信息
Signature signature = joinPoint.getSignature();
//获取连接点所对应方法的参数
Object[] args = joinPoint.getArgs();
System.out.println("前置通知:" + "方法名为:" + signature.getName());
}
//2.后置通知
@After("pointCut()")
public void afterMethod(JoinPoint joinPoint){
Signature signature = joinPoint.getSignature();
System.out.println("后置通知:" + "方法名为:" + signature.getName());
}
//3.返回通知
@AfterReturning(value = "pointCut()",returning = "result")
public void afterReturning(JoinPoint joinPoint,Object result){
Signature signature = joinPoint.getSignature();
System.out.println("返回通知:" + "返回结果为:" + result);
}
//4.异常通知
@AfterThrowing(value = "pointCut()",throwing = "ex")
public void afterThrowing(JoinPoint joinPoint,Exception ex){
Signature signature = joinPoint.getSignature();
System.out.println("返回通知:" + "异常为:" + ex);
}
//5.环绕通知
@Around("pointCut()")
@Order(value=1)
public Object aroundMethod(ProceedingJoinPoint joinPoint){
String name = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
Object result = null;
try {
System.out.println("环绕通知:目标对象方法执行之前");
//使用proceed()方法表示目标对象方法的执行
result = joinPoint.proceed();
System.out.println("环绕通知:目标对象方法执行之后");
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println("环绕通知:目标对象方法执行异常");
}finally {
System.out.println("环绕通知:目标对象方法执行完毕");
}
return result;
}
}
5.@Pointcut:声明一个公共的切入点表达式的注解
功能:声明一个公共的切入点表达式,可以被其他通知方法注解使用时调用;
代码示例:调用方法如下:
//可重用的切入点表达式
@Pointcut("execution(* com.gz.spring.annotation.CalculatorImpl.*(..))")
//切入点表达式:execution(* com.gz.spring.annotation.CalculatorImpl.*(..))
public void pointCut(){
}
@Before("pointCut()")
public void beforeAdviceMethod(JoinPoint joinPoint){
//获取连接点所对应方法的信息
Signature signature = joinPoint.getSignature();
//获取连接点所对应方法的参数
Object[] args = joinPoint.getArgs();
System.out.println("前置通知:" + "方法名为:" + signature.getName());
}
6.@Order:设置切面优先级的注解
1.功能
通过@Order注解的value属性设置优先级,@Order注解的value属性值越小,优先级越高
2.代码示例
@Order(value=1)
public Object aroundMethod(ProceedingJoinPoint joinPoint){
return "order设置切面优先级";
}
7.@RunWith:指定测试环境的注解
1.功能
Spring中已经整合了JUnit,因此可以通过@RunWith注解,指定当前测试类在Spring的测试环境中执行,此时就可以通过注入的方式,直接获取IOC容器中bean
2.代码示例
//指定当前测试类在Spring的测试环境中执行,此时可以通过注入的方式直接获取ioc容器中bean
@RunWith(SpringJUnit4ClassRunner.class)
public class testRunWith{
}
8.@Transaction:管理声明式事务的注解
1.功能
@Transaction标识在类上时,类中所有的方法都会被事务管理
2.代码示例
@Transactional(
rollbackFor = Exception.class
rollbackForClassName = java.lang.Exception
noRollbackFor = Exception.class
noRollbackForClassName = java.lang.Exception
)
关于@Transaction的属性的详细说明:请参考
Spring管理事务知识_perseveregz的博客-CSDN博客
9.@RequestMapping:建立映射关系的映射
1.功能
将请求和处理请求的控制器方法关联起来,建立映射关系,SpringMVC接收到指定的请求,就会找到在映射关系中对应的控制器方法来处理这个请求
2.@RequestMapping注解的位置
* RequestMapping标识一个类:设置映射请求的请求路径的初始信息
* RequestMapping标识一个方法:设置映射请求的请求路径的具体信息
3.@RequestMapping的value属性值
* 作用:通过请求的请求路径匹配请求
* value属性是数组类型,即当前浏览器所发送请求的请求路径匹配value属性中的任何一个值,则当前请求就会被注解所表示的方法进行处理
4.@RequestMapping的method属性值
* 作用:通过请求的请求方式来匹配请求
* Method类型为:RequestMethod-枚举类的数组,当前浏览器所发送请求的请求方式匹配method属性中任何一个方式,则当前请求会被注解所标识的方法处理。
* RequestMethod:提供了:get、post、head、options、put、patch、delete、trace等方式
* 只有表单提交时将method设置为post,其他方式基本为get方式(比如超链接、浏览器中地址栏直接访问)
* 若浏览器所发送的请求的请求路径和@RequestMapping注解value属性匹配,但是请求方式不匹配,此时页面报错:405-Requeat method … not supported
// requestMapping的value属性:数组类型
@RequestMapping(
value = {"/demo3", "/a?a","/demo4"},
method = {RequestMethod.GET,RequestMethod.POST,RequestMethod.PUT,RequestMethod.DELETE}
)
public String testThree() {
return "demo3";
}
10.@GetMapping/@PostMapping/@DeleteMapping/@PutMapping:处理不同请求的注解
1.功能
相当于@RequestMapping注解的method属性值为get、post、put、delete
比如@GetMapping源码:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(
method = {RequestMethod.GET}
)
public @interface GetMapping {
2.使用方式
@GetMapping("/demo2")
public String testTwo() {
return "demo2";
}
11.@PathVariable:绑定路径中的占位符与形参的注解
1.功能
将占位符所标识的值与控制器方法的形参进行绑定
2.代码示例
若thymeleaf语法写为:
<a th:href="@{/aaa/1/占位符}">测试占位符赋值</a><br/>
则@PathVariable使用方法为:
@RequestMapping("/aaa/{id}/{name}")
public String testFive(@PathVariable("id") String id,@PathVariable("name") String name){
System.out.println("id = " + id + ",name = " + name);
return "demo3";
}
12.@RequestParam:获取请求参数的注解
1.功能
获取请求参数需要在控制器方法的形参位置,设置一个形参,形参的名字和请求参数的名字一致即可;@RequestParam用在当二者名字不一致时,使用@RequestParam将请求参数和控制器方法的形参绑定
2.代码示例
@RequestMapping("/param/servletAPI")
public String testSix(@RequestParam("name") String userName,String password){
System.out.println("username = " + name+",password=" + password);
return "demo3";
}
13. @ResponseBody:将返回值直接响应的注解
1.功能
用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体响应到浏览器
2.代码示例
@RequestMapping("/test/ResponseBody")
@ResponseBody
public String testResponseBody(){
return "success";
}
14.@RestController:相当于@ResponseBody + @Controller
1.功能
SpringMVC的一个复合注解,标识在控制器的类上,相当于为类添加了@Controller注解,并为其中的每个方法添加了@ResponseBody注解
2.源码示例
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
@AliasFor(
annotation = Controller.class
)
String value() default "";
}
15.@Configuration + @Bean:一起使用代替xml配置文件的注解
1.功能
使用@Configuration + @Bean的方式,@Configuration将类设置为配置类,@Bean标注在方法上用来注册bean对象。
1.1@Configuration
相当于将该类设置为一个xml配置文件
1.2@Bean
相当于xml配置文件中的bean元素,用来注册bean对象;
默认将方法名称作为bean名称,将方法返回值作为bean对象,注册到spring容器中
2.代码示例
2.1配置方法
xml文件配置对比@Configuration + @Bean配置:
<beans>
<bean id="hello" class="com.gz.spring.pojo.HelloWorld"></bean>
</beans>
@Configuration
public class ConfBean {
@Bean("hello")
public HelloWorld HelloWorld(){
return new HelloWorld();
}
}
2.2使用方法
@Test
public void testSayHello(){
//1.获取ioc容器
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取ioc容器中的bean对象
HelloWorld hello = (HelloWorld) ioc.getBean("hello");
hello.sayHello();
}
@Test
public void testBean(){
//1.使用AnnotationConfigApplicationContext加载修饰类
AnnotationConfigApplicationContext confbean = new AnnotationConfigApplicationContext(ConfBean.class);
//2.获取容器中的bean对象
HelloWorld helloWorld = (HelloWorld)confbean.getBean("hello");
helloWorld.sayHello();
}
16.@Import:为容器导入指定的组件的注解
1.功能
能够为容器中自动创建出导入类型的组件,默认组件名为全类名
2.代码示例
@Import(HelloWorld.class)
public class ConfBean {
}
17.@Conditional:条件装配的注解
1.功能
满足@Conditional指定的条件,才会进行组件注入
2.代码示例
若使用ConditionalOnBean标注一个方法user()时,指定存在testConditional组件才注册这个方法的组件;
@ConditionalOnBean(name = "testConditional")
@Bean
public User user(){
return new User();
}
18.@ImportResource:导入资源的注解
1.功能
导入资源注解:比如导入Spring的配置文件;将某个已经写好的xml导入到配置类使用,不需要再一个一个转换为配置类中的方法
2.代码示例
@ImportResource("application.properties")
public class test{
}
19..@SpringBootApplication
1.出现位置
使用Spring Initializr创建一个Spring Boot项目后,该注解会自动标记在主类上
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(MyblogApplication.class, args);
}
}
2.源码分析
从源码可以看出SpringBootApplication注解可以看作是@SpringBootConfiguration+@EnableAutoConfiguration+@ComponentScan的集中体现,自然具备这几个注解的功能
@SpringBootConfiguration:在Spring上下文中管理bean,导入配置类,内部是一个@Configuration,代表当前类是一个配置类
@EnableAutoConfiguration:启用自动装配功能
@ComponentScan:自动扫描被@Component/@Controller/@Service/@Repository标注的类
@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 {
}
20.lombok自带注解:@Data、@ToString、@AllArgsConstructor、@NoArgsContructor、@Slf4j
1.功能
自动生成javaBean的@Data注解(get,set方法)、@ToString注解、@AllArgsConstructor(有参构造器)、@NoArgsContructor-无参构造器、@Slf4j-日志
注意:前提是已经安装了lombok插件
2.代码示例
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class User {
private String userName;
private String password;
}