摘要:本文主要总结了一些Spring和Spring MVC中常用的注解。
前言:今天总结了一下这周所学习的内容,这是第一篇Spring中常用注解的总结。
Spring中常用注解
1、声明bean的注解
@Component:这个更多对应的是一个组件的概念,如果一个Bean不知道属于哪个层,可以使用@Component注解标注
- @Component作用在类上
- @Component注解作用域默认为singleton
- 使用注解配置和类路径扫描时,被@Component注解标注的类会被Spring扫描并注册为Bean
- @Component使用在不确定哪一个层的时候使用,可以作用在任何层次,把普通pojo实例化到spring容器,不推荐使用@Component注解,而应该使用它的扩展,如@Service、@Repository
- @Component使用时没有传参数,Bean名称默认为当前类的类名,首字母小写
- @Component(“serviceBeanId”)或 @Component(value=”serviceBeanId”)使用时传参数,使用value作为Bean名字
@Service:对应的是服务层即Service层,其作用是对单条/多条Sql语句进行组合处理,当然如果简单的话就直接调用Dao层的某个方法了
@Service是@Component注解的一个特例,作用在类上
@Service注解作用域默认为singleton
使用注解配置和类路径扫描时,被@Service注解标注的类会被Spring扫描并注册为Bean
@Service用于标注业务层组件,表示定义一个bean
@Service使用时没有传参数,Bean名称默认为当前类的类名,首字母小写
@Service(“serviceBeanId”)或 @Service(value=”serviceBeanId”)使用时传参数,使用value作为Bean名字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52/* @service注解举例 */
public interface IUser {
public String get();
}
package com.example.demo.annotation.service;
public class UserServiceImpl implements IUser {
private final String name = "UserServiceImpl";
public String get () {
return name;
}
}
//@Service("userService")
public class UserServiceImplWithParam implements IUser {
private String name = "UserServiceImplWithParam";
public String get() {
return name;
}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import com.example.demo.DemoApplication;
import com.example.demo.annotation.IUser;
public class ServiceApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
IUser serviceImpl1 = (UserServiceImpl) context.getBean("userServiceImpl");
System.out.println(serviceImpl1.get());
IUser serviceImpl2 = (UserServiceImplWithParam)context.getBean("userService");
System.out.println(serviceImpl2.get());
}
}
/**
* 结果为:
userServiceImpl
UserServiceImplWithParam
*/
@Repository:对应的是持久层即Dao层,其作用是直接和数据库交互,通常来说一个方法对应一条具体的Sql语句
- @Repository注解作用在类上
- @Repository注解作用域默认为singleton
- 使用注解配置和类路径扫描时,被@Reposito注解标注的类会被Spring扫描并注册为Bean
- @Repository注解用于标注数据访问组件,即DAO组件
- @Repository注解的作用不只是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/* @Repository注解举例 */
import org.springframework.stereotype.Repository;
// @Repository注解默认作用域为singleton
public class UserRepositoryImpl {
public UserRepositoryImpl () {
}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
// @Repository注解测试
public class RepopsitoryApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(RepopsitoryApplication.class, args);
UserRepositoryImpl userRepositoryImpl1 = (UserRepositoryImpl) context.getBean("userRepositoryImpl");
UserRepositoryImpl userRepositoryImpl2 = (UserRepositoryImpl) context.getBean("userRepositoryImpl");
System.out.println("@Repository注解默认作用域为singleton,返回true: " + userRepositoryImpl1.equals(userRepositoryImpl2));
}
}
/**
* 结果为:@Repository注解默认作用域为singleton,返回true:true
*/
@Controller:对应的是控制层即MVC设计模式中的控制层,其作用是接收用户请求,根据请求调用不同的Service取数据,并根据需求对数据进行组合、包装返回给前端
- @Controller注解作用在类上
- 使用注解配置和类路径扫描时,被@Controller注解标注的类会被Spring扫描并注册为Bean
- @Controller用于标注Web中控制层组件
- 被@Controller标注的类负责处理由DispatcherServlet分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model返回给对应的View进行展示
- @Controller和@RequestMapping、@RequestParam等一些注解共同处理URL的映射
2、@Bean的属性支持
@Scope:
@Scope作用在类上和方法上
@Scope用来配置 spring bean 的作用域,它标识 bean 的作用域
@Scope有5中取值:
基本作用域:
- org.springframework.beans.factory.config.ConfigurableBeanFactory.SCOPE_SINGLETON = “singleton”
- org.springframework.beans.factory.config.ConfigurableBeanFactory.SCOPE_PROTOTYPE = “prototype”
Web作用域:
- org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST = “request”
- org.springframework.web.context.WebApplicationContext#SCOPE_SESSION = “session”
- org.springframework.web.context.WebApplicationContext#SCOPE_APPLICATION = “application”
singleton单例模式:
Spring 容器中有且只有一个Bean实例,只要Spring容器不销毁或退出,该Bean实例就会一直存活。
prototype原型模式:
每次获取Bean的时候会有一个新的实例,Spring容器不能对返回Bean实例的整个生命周期负责。
request模式:
request只适用于Web程序,每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效,当请求结束后,该对象的生命周期即告结束。
session模式:
session只适用于Web程序,session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效。
application模式:
application只适用于Web程序,全局作用域。
@StepScope 在Spring Batch中还有涉及
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public StepScope
/*
Convenient annotation for step scoped beans that defaults the proxy mode, so that it doesn't have to be
specified explicitly on every bean definition. Use this on any @Bean that needs to inject @Values from the step
context, and any bean that needs to share a lifecycle with a step execution (e.g. an ItemStream). E.g.
*/
protected Callable<String> value( final String value) {
return new SimpleCallable(value);
}
/* Marking a @Bean as @StepScope is equivalent to marking it as @Scope(value="step", proxyMode=TARGET_CLASS) */@PostConstruct:被 @PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Serclet的inti()方法。被 @PostConstruct修饰的方法会在构造函数之后,init()方法之前运行。
@PreDestory:被 @PreDestroy修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法。被 @PreDestroy修饰的方法会在destroy()方法之后运行,在Servlet被彻底卸载之前。
3、注入bean的注解
@Autowired:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/* 源码 */
package org.springframework.beans.factory.annotation;
/**
1. @since 2.5
2. @see AutowiredAnnotationBeanPostProcessor
3. @see Qualifier
4. @see Value
*/
public Autowired {
boolean required() default true;
}- @Autowired注解作用在构造函数、方法、方法参数、类字段以及注解上
- @Autowired注解可以实现Bean的自动注入
原理:
在Spring Boot应用启动时,Spring容器会自动装载一个org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor处理器,当容器扫描到@Autowired注解时,就会在IoC容器就会找相应类型的Bean,并且实现注入。
- 在使用@Autowired注解时,首先在容器中查询对应类型的bean
- 如果查询结果Bean刚好为一个,自动注入
- 如果查询结果Bean不止一个,通过@Qualifier注解指定自动装配Bean的名称
- 如果没有查询到对应类型的Bean,由于默认@Autowired(required=true),会抛出异常,解决方法是使用@Autoiwired(required=false)
- @Autowired(required=true)意味着依赖是必须的
- @Autowired(required=false)等于告诉 Spring:在找不到匹配 Bean 时也不报错
使用:
在Web MVC中控制层(Controller)访问的是业务层(Service),而业务层(Service)访问的是数据层(Dao),使用@Autowired注解实现注入。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55/**
* 数据层接口,用于访问数据库,返回数据给业务层
* */
public interface IDao {
public String get();
}
/**
* 数据层接口实现类
*
* 1.数据层Bean用@Repository标注
* 2.当前Bean的名称是"autowiredUserDaoImpl"
* 3.设置当前Bean的为原型模式,即每次获取Bean时都创建一个新实例
* */
public class UserDaoImpl implements IDao {
public String get() {
return "@Autowired注解实现自动装配";
}
}
/**
* 业务层接口
* 从数据层获取数据,处理结果返回给控制层
* */
public interface IService {
public String get();
}
/**
* 业务层接口实现
*
* 1.数据层Bean用@Service标注
* 2.当前Bean的名称是"autowiredUserServiceImpl"
* 3.设置当前Bean的为原型模式,即每次获取Bean时都创建一个新实例
* 4.业务层有一个数据层接口IDao,使用@Autowired注解标注
* */
public class UserServiceImpl implements IService {
/**
* @Autowired实现自动装配
* Spring IoC容器扫描到@Autowired注解会去查询IDao的实现类,并自动注入
* */
private IDao dao;
public String get() {
return dao.get();
}
}- Bean通过注解@Service声明为一个Spring容器管理的Bean,Spring容器会扫描classpath路径下的所有类,找到带有@Service注解的UserServiceImpl类,并根据Spring注解对其进行初始化和增强,命名为autowiredUserServiceImpl。
- Spring容器如果发现此类属性dao也有注解@Autowired,则会从Spring容器中查找一个已经初始化好的IDao的实现类,如果没有找到,则先初始化一个IDao实现类。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.chapter1.useannotation.autowired.service.IService;
/**
1. 控制层
2.
3. 1.控制层使用@RestController注解标注,返回json格式的字符串
4. 2.获取业务层返回的数据,输出到客户端
5. 3.请求:http:localhost:8080/autowiredController
6. */
public class AutowiredController {
private IService service;
public String get () {
return service.get();
}
}@Inject: @Inject支持构造函数、方法和字段注解,也可能使用于静态实例成员。可注解成员可以是任意修饰符(private,package-private,protected,public)。注入顺序:构造函数、字段,然后是方法。父类的字段和方法注入优先于子类的字段和方法,同一类中的字段和方法是没有顺序的。
@Inject注解的构造函数可以是无参或多个参数的构造函数。@Inject每个类中最多注解一个构造函数。
在字段注解:
- 用@Inject注解
- 字段不能是final的
- 拥有一个合法的名称
在方法上注解:
- 用@Inject注解
- 不能是抽象方法
- 不能声明自身参数类型
- 可以有返回结果
- 拥有一个合法的名称
- 可以有0个或多个参数
@Resource:@Resource(这个注解属于J2EE的),默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行,按照名称查找,如果注解写在setter方法上默认取属性名进行装配。 当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
1
2
private BaseDao baseDao;
4、java配置类相关注解
@Configuration 声明当前类为配置类,相当于xml形式的Spring配置(类上)。
@Bean 注解在方法上,声明当前方法的返回值为一个bean,替代xml中的方式(方法上)。
@Configuration 声明当前类为配置类,其中内部组合了@Component注解,表明这个类是一个bean(类上)。
@ComponentScan 用于对Component进行扫描,相当于xml中的(类上)。
@WishlyConfiguration 为@Configuration与@ComponentScan的组合注解,可以替代这两个注解。
5、切面(AOP)相关注解
Spring支持AspectJ的注解式切面编程。
@Aspect 声明一个切面(类上):使用@After、@Before、@Around定义建言(advice),可直接将拦截规则(切点)作为参数。
- @After 在方法执行之后执行(方法上)
- @Before 在方法执行之前执行(方法上)
- @Around 在方法执行之前与之后执行(方法上)
@PointCut 声明切点:在java配置类中使用@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持(类上)
6、@Value注解
@Value 为属性注入值(属性上)
支持如下方式的注入:
- 注入普通字符:
1 |
|
- 注入操作系统属性
1 |
|
- 注入表达式结果
1 |
|
- 注入其他bean属性
1 |
|
- 注入文件资源
1 |
|
- 注入网站资源
1 |
|
- 注入配置文件
1 |
|
注入配置使用方法
①. 编写配置文件(test.properties)
②. @PropertySource加载配置文件(类上)
③. 还需要配置一个PropertySourcesPlaceholderConfigurer的bean
7、环境切换
- @Profile 通过设定Environment的ActiveProfiles来设定当前context需要使用的配置环境。(类或方法上)
- @Conditional Spring4中可以使用此注解定义条件话的bean,通过实现Condition接口,并重写matches方法,从而决定该bean是否被实例化。(方法上)
8、异步相关
- @EnableAsync 配置类中,通过此注解开启对异步任务的支持,叙事性AsyncConfigurer接口(类上)
- @Async 在实际执行的bean方法使用该注解来申明其是一个异步任务(方法上或类上所有的方法都将异步,需要@EnableAsync开启异步任务)
9、定时任务相关
- @EnableScheduling 在配置类上使用,开启计划任务的支持(类上)
- @Scheduled 来申明这是一个任务,包括cron,fixDelay,fixRate等类型(方法上,需先开启计划任务的支持)
10、@Enable*注解说明
这些注解主要用来开启对xxx的支持:
@EnableAspectJAutoProxy 开启对AspectJ自动代理的支持
@EnableAsync 开启异步方法的支持
@EnableScheduling 开启计划任务的支持
@EnableWebMvc 开启Web MVC的配置支持
@EnableConfigurationProperties 开启对@ConfigurationProperties注解配置Bean的支持
@EnableJpaRepositories 开启对SpringData JPA Repository的支持
@EnableTransactionManagement 开启注解式事务的支持
@EnableTransactionManagement 开启注解式事务的支持
@EnableCaching 开启注解式的缓存支持
11、测试相关注解
- @RunWith 运行器,Spring中通常用于对JUnit的支持
1 |
- @ContextConfiguration 用来加载配置ApplicationContext,其中classes属性用来加载配置类
1 |
Spring MVC中常用注解
@EnableWebMvc 在配置类中开启Web MVC的配置支持,如一些ViewResolver或者MessageConverter等,若无此句,重写WebMvcConfigurerAdapter方法(用于对SpringMVC的配置)。
@Controller 声明该类为SpringMVC中的Controller
@RequestMapping RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
@ResponseBody 支持将返回值放在response内,而不是一个页面,通常用户返回json数据(返回值旁或方法上)
@RequestBody 允许request的参数在request体中,而不是在直接连接在地址后面。(放在参数前)
@PathVariable 用于接收路径参数,比如@RequestMapping(“/hello/{name}”)申明的路径,将注解放在参数中前,即可获取该值,通常作为Restful的接口实现方法。
@RestController 该注解为一个组合注解,相当于@Controller和@ResponseBody的组合,注解在类上,意味着,该Controller的所有方法都默认加上了@ResponseBody。
@ControllerAdvice 通过该注解,我们可以将对于控制器的全局配置放置在同一个位置,注解了@Controller的类的方法可使用@ExceptionHandler、@InitBinder、@ModelAttribute注解到方法上,这对所有注解了 @RequestMapping的控制器内的方法有效。
@ExceptionHandler 用于全局处理控制器里的异常
@InitBinder 用来设置WebDataBinder,WebDataBinder用来自动绑定前台请求参数到Model中。
@ModelAttribute 本来的作用是绑定键值对到Model里,在@ControllerAdvice中是让全局的 @RequestMapping都能获得在此处设置的键值对。
其它注解
@SpringBootApplication: @SpringBootApplication是一个复合注解,包括@ComponentScan,和@SpringBootConfiguration,@EnableAutoConfiguration。
@SpringBootConfiguration继承自@Configuration,二者功能也一致,标注当前类是配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到srping容器中,并且实例名就是方法名。
@EnableAutoConfiguration的作用启动自动的配置,@EnableAutoConfiguration注解的意思就是Springboot根据你添加的jar包来配置你项目的默认配置,比如根据spring-boot-starter-web ,来判断你的项目是否需要添加了webmvc和tomcat,就会自动的帮你配置web项目中所需要的默认配置。在下面博客会具体分析这个注解,快速入门的demo实际没有用到该注解。
@ComponentScan,扫描当前包及其子包下被@Component,@Controller,@Service,@Repository注解标记的类并纳入到spring容器中进行管理。是以前的context:component-scan(以前使用在xml中使用的标签,用来扫描包配置的平行支持)。所以本demo中的User为何会被spring容器管理。
@RestController
Spring4之后新加入的注解,原来返回json需要@ResponseBody和@Controller配合。
即@RestController是@ResponseBody和@Controller的组合注解。
1 |
|
- @Slf4j
@slf4j注解用于打印日志,如果注解@Slf4j注入后找不到变量log,那就给IDE安装lombok插件
安装步骤:
Settings→Plugins→Browse repositories→lombok plugin
- @Override
如果想重写父类的方法,比如toString()方法的话,在方法前面加上@Override 系统可以帮你检查方法的正确性。它说明了被标注的方法重载了父类的方法,起到了断言的作用。
- 本文作者: th3ee9ine
- 本文链接: https://www.blog.ajie39.top/2021/05/05/Spring中常用的注解/
- 版权声明: 本博客所有文章除特别声明外,均采用 LICENSE 下的许可协议。转载请注明出处!