Java常见注解

注解(Annotation)是Java 5引入的一种元数据机制,用于在代码中添加额外的信息。注解可以被编译器、工具或运行时环境使用,以提供更丰富的功能和更好的代码质量。以下是一些Java中常见的注解:

  • 元注解(用来修饰注解的注解)
  • Spring相关注解
    • SpringMVC注解
    • IOC容器注解
    • Bean注解
    • Spring启动类注解
    • 请求Mapping注解
    • 动态赋值注解
    • 缓存注解
  • AOP切面注解

一、元注解

1.1 元注解

元注解用来定义注解本身

@Retention

@Retention:描述注解的生命周期,指定注解在哪个阶段可用。常用的取值有:

  • SOURCE: 注解只在源代码中存在,编译后就不存在了
  • CLASS: 注解在class文件中存在,但运行时不可
  • RUNTIME: 注解在运行时也存在,可以通过反射获取
1
2
3
4
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value();
}

@Target

@Target:描述注解使用范围,指定注解可以应用于哪些Java元素。常用的取值有:

  • CONSTRUCTOR: 用于描述构造器
  • FIELD: 用于描述域
  • LOCAL_VARIABLE: 用于描述局部变量
  • METHOD: 用于描述方法
  • PACKAGE: 用于描述包
  • PARAMETER: 用于描述参数
  • TYPE: 用于描述类、接口(包括注解类型)或enum声明
1
2
3
4
@Target(ElementType.METHOD)
public @interface MyAnnotation {
String value();
}

@Documented

@Documented:表示该注解会被javadoc工具提取成文档。

1
2
3
4
@Documented
public @interface MyAnnotation {
String value();
}

@Inherited

@Inherited:表示子类可以继承父类的注解。

1
2
3
4
@Inherited
public @interface MyAnnotation {
String value();
}

@Repeatable

@Repeatable:表示注解可以重复使用。

1
2
3
4
@Repeatable(MyAnnotations.class)
public @interface MyAnnotation {
String value();
}

二、Spring相关注解

2.1 SpringMVC注解

这些注解描述的类Spring会创建原生对象或代理对象并交给IOC容器管理,这些对象称之为bean。用时直接 @Autowired 注入即可。

@Mapper

@Mapper:描述数据层(Mapper),Mybatis的注解,表示该接口是一个Mybatis的Mapper接口,Spring会为其创建代理对象并交给IOC容器管理。

1
2
3
4
@Mapper
public interface UserMapper {
// ...
}

@Service

@Service:描述业务层(Service),表示该类是一个业务逻辑组件,Spring会为其创建对象并交给IOC容器管理。

1
2
3
4
@Service
public class UserServiceImpl implements UserService {
// ...
}

@Repository

@Repository:标识持久层/数据访问层组件(Dao),表示该类是一个数据访问组件,Spring会为其创建对象并交给IOC容器管理。

1
2
3
4
@Repository
public class UserRepository {
// ...
}

@Component

@Component:描述组件类,表示该类是一个组件,Spring会为其创建对象并交给IOC容器管理。通常用于那些不属于Controller、Service、Repository等特定层次的组件。

1
2
3
4
@Component
public class MyComponent {
// ...
}

@Controller

@Controller:描述控制层(Controller),表示该类是一个控制器组件,Spring会为其创建对象并交给IOC容器管理。通常用于处理用户请求,执行业务逻辑,并返回视图(HTML页面)给客户端。

1
2
3
4
@Controller
public class UserController {
// ...
}

@ResponseBody

@ResponseBody:将Java对象转为JSON数据类型,表示该方法的返回值应该直接作为HTTP响应的内容,而不是被视图解析器处理。通常与@Controller一起使用,用于构建RESTful API。

1
2
3
4
5
6
7
8
@Controller
public class UserController {
@RequestMapping("/user")
@ResponseBody
public User getUser() {
return new User("Alice", 30);
}
}

@RestController

@RestController: = @Controller + @ResponseBody,表示该控制器中的所有方法都默认返回JSON数据类型。适用于构建RESTful API。

1
2
3
4
5
6
7
@RestController
public class UserController {
@RequestMapping("/user")
public User getUser() {
return new User("Alice", 30);
}
}

2.2 IOC容器注解

IOC(Inversion of Control)是控制反转,也叫做依赖注入(Dependency Injection)。
它的核心理念是:对象的创建和依赖关系的管理不由对象自身控制,而由外部容器负责。

简单来说:IOC容器意味着将你设计好的对象(类)交给容器控制(管理),需要的时候通过注解来注入(获取),而不是传统的在你的对象内部直接控制(new 对象)。从而降低了程序的耦合性。

@Bean

@Bean:描述在方法上,把方法的返回值交给容器管理,不需要再手动调用该方法

1
2
3
4
@Bean
public UserService userService() {
return new UserService();
}

@Autowired

@Autowired:按byType自动注入获取对应的bean对象。如果注入的类型有多个实现,则需要注入具体实现类的名称

1
2
@Autowired
private UserService userService;

@Resource

@Resource:按byName自动注入获取对应的bean对象

1
2
@Resource(name = "userService")
private UserService userService;

@Value

@Value:注入普通类型属性

1
2
@Value("${app.name}")
private String appName;

@Qualifier

@Qualifier:在相同类型bean上命名后,可以按不同名注入,配合@Autowired使用

1
2
3
@Autowired
@Qualifier("userServiceImpl")
private UserService userService;

@Primary

@Primary:当存在多个想用类型的bean时,首选被@Primary注解过的bean

1
2
3
4
5
@Service
@Primary
public class UserServiceImpl implements UserService {
// ...
}

2.3 Bean注解

Bean是由Spring IOC容器创建和管理的对象,其生命周期、依赖注入等都由容器统一控制。

当你使用上面的SpringMVC注解时,Spring会把这些注解的类的实例化对象转化为一个个的bean,也称注册成一个个bean对象,交给IOC容器管理。

@Scope

@Scope(value=""):描述bean的作用域,默认是单例(singleton)

1
2
3
4
5
@Service
@Scope("prototype")
public class UserServiceImpl implements UserService {
// ...
}

@PostConstruct

@PostConstruct:在bean创建完成后执行的方法,通常用于初始化操作,相当于XML配置中的init-method

1
2
3
4
@PostConstruct
public void init() {
// 初始化操作
}

@PreDestroy

@PreDestroy:在bean销毁前执行的方法,通常用于清理资源,相当于XML配置中的destroy-method

1
2
3
4
@PreDestroy
public void destroy() {
// 清理资源
}

2.4 Spring启动类注解

@SpringBootApplication

@SpringBootApplication:是一个组合注解,包含了@Configuration@EnableAutoConfiguration@ComponentScan三个注解的功能。表示这是一个Spring Boot应用的入口类。

  • @SpringBootConfiguration继承自@Configuration,标注当前类是配置类,将当前类的一个或多个以@Bean注解标记的方法的实例纳入到Spring容器中,并且实例名就是方法名。
  • @EnableAutoConfiguration自动化配置, 借助@Import的支持,收集和注册特定场景相关的bean定义。简单理解:借助@Import的帮助,将所有符合自动配置条件的bean定义加载到IOC容器中。该注解里面有@AutoConfigurationPackage自动配置的包扫描 @Import调用选择器去加载pom.xml文件中的启动项
  • @ComponentScan定义包扫描指定路径哪些包中的对象注册成bean交给IOC容器管理。
1
2
3
4
5
6
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

2.5 请求Mapping注解

@RequestMapping

@RequestMapping:描述请求映射,表示该方法处理哪个URL的请求,可以指定请求方法(GET、POST等)、请求参数、请求头等信息。

1
2
3
4
@RequestMapping("/user")
public User getUser() {
return new User("Alice", 30);
}

@GetMapping

@GetMapping:查询方法。是@RequestMapping(method = RequestMethod.GET)的缩写,表示该方法处理GET请求。

1
2
3
4
@GetMapping("/user")
public User getUser() {
return new User("Alice", 30);
}

@PostMapping

@PostMapping:增添保存方法。是@RequestMapping(method = RequestMethod.POST)的缩写,表示该方法处理POST请求。

1
2
3
4
5
@PostMapping("/user")
public User createUser(@RequestBody User user) {
// 创建用户逻辑
return user;
}

@PutMapping

@PutMapping:更新方法。是@RequestMapping(method = RequestMethod.PUT)的缩写,表示该方法处理PUT请求。

1
2
3
4
5
@PutMapping("/user/{id}")
public User updateUser(@PathVariable Long id, @RequestBody User user) {
// 更新用户逻辑
return user;
}

@DeleteMapping

@DeleteMapping:删除方法。是@RequestMapping(method = RequestMethod.DELETE)的缩写,表示该方法处理DELETE请求。

1
2
3
4
@DeleteMapping("/user/{id}")
public void deleteUser(@PathVariable Long id) {
// 删除用户逻辑
}

@PatchMapping

@PatchMapping:更新局部方法。是@RequestMapping(method = RequestMethod.PATCH)的缩写,表示该方法处理PATCH请求。

1
2
3
4
5
@PatchMapping("/user/{id}")
public User partiallyUpdateUser(@PathVariable Long id, @RequestBody Map<String, Object> updates) {
// 部分更新用户逻辑
return updatedUser;
}

2.6 动态赋值注解

@PathVariable

@PathVariable:描述路径变量,接收url动态传给备注接的参数,表示该参数的值来自URL路径中的占位符。

1
2
3
4
5
@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) {
// 根据id获取用户逻辑
return user;
}

@RequestBody

@RequestBody:描述请求体,将接收的JSON格式数据转化为Java对象参数。适用于Post、Put、Patch等请求方法。

1
2
3
4
5
@PostMapping("/user")
public User createUser(@RequestBody User user) {
// 创建用户逻辑
return user;
}

@RequestParam

@RequestParam(value=""):描述请求参数,将接收的参数值传给被注解的参数。

1
2
3
4
5
@GetMapping("/user")
public User getUser(@RequestParam("id") Long id) {
// 根据id获取用户逻辑
return user;
}

2.7 缓存注解

@EnableCaching

@EnableCaching:启用Spring的缓存功能,表示该应用支持缓存。

1
2
3
4
@EnableCaching
public class Application {
// ...
}

@Cacheable

@Cacheable(value="缓存值名"):描述可缓存的方法,表示该方法的结果可以被缓存起来,下次调用时直接从缓存中获取结果,而不需要执行方法体。

1
2
3
4
5
@Cacheable("users")
public User getUserById(Long id) {
// 从数据库获取用户逻辑
return user;
}

@CacheEvict

@CacheEvict(value="需要清空的缓存值名"):描述清除缓存的方法,表示该方法执行后会清除指定缓存中的数据。

1
2
3
4
@CacheEvict("users")
public void deleteUserById(Long id) {
// 删除用户逻辑
}

三、AOP切面注解

3.1 AOP切面注解

AOP(Aspect Oriented Programming) 面向切面编程。

Spring中的AOP代理还是离不开Spring的IOC容器,代理的生成,管理及其依赖关系都是由IOC容器负责,Spring默认使用JDK动态代理。

@Aspect

@Aspect:描述切面类,表示该类是一个切面,Spring会为其创建对象并交给IOC容器管理。切面类中可以定义切点和通知。

1
2
3
4
5
@Aspect
@Component
public class LoggingAspect {
// 定义切点和通知
}

@Pointcut

@Pointcut("@annotation(被切入方法的地址)"):定义切点,表示一个切点表达式,指定在哪些方法上应用切面逻辑。

1
2
3
4
@Pointcut("@annotation(com.example.annotation.LogExecutionTime)")
public void Pointcut() {
// 切点方法体可以为空
}

@Before

@Before("切点方法名()"):前置通知,表示在切点方法执行之前执行该方法。

1
2
3
4
@Before("Pointcut()")
public void beforeAdvice() {
// 前置通知逻辑
}

@After

@After("切点方法名()"):后置通知,表示在切点方法执行之后执行该方法。

1
2
3
4
@After("Pointcut()")
public void afterAdvice() {
// 后置通知逻辑
}

@AfterReturning

@AfterReturning("切点方法名()"):返回通知,表示在切点方法正常返回之后执行该方法。

1
2
3
4
@AfterReturning(value = "pointCut()", returning = "result")
public void afterReturning(Object result) {
System.out.println("返回值:" + result);
}

@AfterThrowing

@AfterThrowing("切点方法名()"):异常通知,表示在切点方法抛出异常之后执行该方法。

1
2
3
4
@AfterThrowing(value = "pointCut()", throwing = "ex")
public void afterThrowing(Exception ex) {
System.out.println("异常:" + ex.getMessage());
}

@Around

@Around("切点方法名()"):环绕通知,表示在切点方法执行前后都执行该方法,可以控制切点方法的执行。

1
2
3
4
5
6
7
@Around("pointCut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("前置");
Object result = pjp.proceed(); // 执行目标方法
System.out.println("后置");
return result;
}

参考资料: