java 注解

本文介绍了Java注解的分类,包括运行机制划分和来源划分。详细讲解了自定义注解的实现,如使用@interface定义注解并用@Target、@Retention、@Inherited和@Documented元注解进行说明。还探讨了第三方注解如Spring和SpringBoot中的常见注解,如@Configuration、@Bean、@Value、@Autowired等,以及它们在实际开发中的用途。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注解分类

一、运行机制划分:

  • 源码注解
  • 编译时注解 (只在编译器时起作用)
  • 运行时注解(运行阶段起作用,影响运行逻辑,例如@Autowired)

二、按照来源划分:

  • jdk自带注解
    @Override
    @Depreted
    @SuppressWarning(“deprecation”)
  • 自定义注解
  • java第三方注解
    Spring注解
    SpringBoot注解

自定义注解

一、 实现
使用@interface定义自定义注解时,通常可以使用下面四种元注解对注解进行说明:
@Target 元注解:注明自定义注解可以放置的位置
@Retention 元注解:注明自定义注解的作用区间
@Inherited 元注解:注明自定义注解是否可以被继承
@Documented 元注解:注明生成javadoc会包含该自定义注解信息

@Target({})
@Retention
@Inherited
@Documented
public @interface Description{
	//成员变量以无参无异常的方式声明 
	//成员类型受限于8种基本类型和String,Class,Annotation,Enumeration
	String desc();
	String author();
	int age() default 18;
}

//只有一个成员变量时,名称必须为value(),使用时可忽略'='或成员名
public @interface Description{
	String value();
}

//没有成员的注解成为标识注解
public @interface Description{
}

实例

// CONSTRUCTOR:构造方法声明  FIELD:字段 LOCAL_VARIABLE:局部变量 
// METHOD:方法 PACKAGE:包  PARAMETER:参数 TYPE:接口.类
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD,ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
	/**
	 * Declares whether the annotated dependency is required.
	 * <p>Defaults to {@code true}.
	 */
	boolean required() default true;
}

二、 注解解析

try{
	//1.找到类上的注解,反射加载类
	Class c = Class.forName("com.zjy.entity.Child");
	//2.找到类上面的注解
	boolean isExist = c.isAnnotationPresent(Description.class);
	if(isExist){
		//3.存在注解实例,取出
		Description d = (Description)c.getAnnotation(Description.class);
		System.out.println(d.value());
	}

	//1.找到方法上的注解
	Method[] ms = c.getMethods();
	for(Method m : ms){
		boolean isExist = m.isAnnotationPresent(Description.class);
		if(isExist){
			//2.存在注解实例,取出
			Description d = (Description)c.getAnnotation(Description.class);
			System.out.println(d.value());
		}
	}
	//1.找到方法所有注解
	for(Method m : ms){
		Annotation[] as = m.getAnnotations();
		for(Annotation a: as){
			if(a instanceod Description){
				Description d = (Description)a;
				System.out.println(d.value());
			}
		} 
	}
}catch(ClassNotFoundException e){
	logger.error("",e);
}

第三方注解

1.@Configuration、@Bean
@Bean是放在方法的注释上了,因为它很明确地告诉被注释的方法,你给我产生一个Bean,然后交给Spring容器,剩下的你就别管了。

@Configuration注解的类等价 与XML中配置beans,相当于Ioc容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean,与xml中配置的bean意思一样。

@Configuration
public class MainConfig {

	public String appid;
    protected MainConfig(){}
 
    @Bean
    public WxMpService wxMpService() {
        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxMpConfigStorage());
        return wxMpService;
	}
}

上述定义一个MainConfig,用@Configuration注解,那MainConfig相当于xml里的beans,里面用@Bean注解的和xml里定义的bean等价,用context:component-scanbase-package=”XXX”/扫描该类,最终我们可以在程序里用@AutoWired或@Resource注解取得用@Bean注解的bean,和用xml先配置bean然后在程序里自动注入一样。目的是减少xml里配置。

2.@Value注解
为了简化从properties里取配置,可以使用@Value, 可以properties文件中的配置值。

@Value("${wx_appid}")
publicString appid;

3.@Controller, @Service, @Repository,@Component
目前4种注解意思是一样,并没有什么太大的区别。

4.@Autowired

@Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。
@Autowired的使用来消除 set ,get方法。
@Autowired默认先按byType,如果发现找到多个bean,则又按照byName方式比对,如果还有多个,则报出异常。
解决方法一:可以在配置bean的时候加上@Primary注解,来提高优先级,这样就不会报错
解决方法二:如果需要直接通过bean的id来查找,可以配合@Qualifier来使用,没有找到抛出异常

通常bean对象在IOC容器中的id(name)就是这个类的全限定名,表示给当前类命名一个别名,方便注入到其他需要用到的类中;不加的话,默认别名就是当前类名,但是首字母小写。

5.@Resource

@Resource由J2EE提供,需要导入包javax.annotation.Resource
@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型
@Resource装配顺序
	1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
	2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
	3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异
	4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配; 

6.@Qualifier、@Primary

这个注解通常和@Autowired一起使用,当你想对注入的过程做更多的控制
@Qualifier可以帮助你指定做更详细配置。一般在两个或者多个bean是相同的类型,spring在注入的时候会出现混乱。
@Primary 优先考虑被注解的对象注入,即一个IOC容器中相同类型对象存在多个,优先使用被该注解注解过的对象

7.@Async

基于@Async标注的方法,称之为异步方法,这个注解用于标注某个方法或某个类里面的所有方法都是需要异步处理的。
被注解的方法被调用的时候,会在新线程中执行,而调用它的方法会在原来的线程中执行

8.@Singleton
只要在类上加上这个注解,就可以实现一个单例类,不需要自己手动编写单例实现类

9.@Valid,@Valided

@Valid是应用在javabean上的校验,且必需使用在以@RequestBody接收参数的情况下
@Validated是应用在javabean上的校验,且必须使用在以@RequestParam接收参数的情况下

10.@RequestBody、@ResponseBody
@RequestBody作用:

  i) 该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上;

  ii) 再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。

使用时机:

A) GET、POST方式提时, 根据request header Content-Type的值来判断:
application/x-www-form-urlencoded, 可选(即非必须,因为这种情况的数据@RequestParam, @ModelAttribute也可以处理,当然@RequestBody也能处理);
multipart/form-data, 不能处理(即使用@RequestBody不能处理这种格式的数据);
其他格式, 必须(其他格式包括application/json, application/xml等。这些格式的数据,必须使用@RequestBody来处理);

B) PUT方式提交时, 根据request header Content-Type的值来判断:
application/x-www-form-urlencoded, 必须;
multipart/form-data, 不能处理;
其他格式, 必须;

说明:request的body部分的数据编码格式由header部分的Content-Type指定;


@ResponseBody 作用

i)该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。

使用时机:

  返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;

11.@RequestParam

作用是提取和解析请求中的参数。@RequestParam支持类型转换,类型转换目前支持所有的基本Java类型。

@RequestParam([value=“num”], [required=false]) String number 将请求中参数为num映射到方法的number上。required=false表示该参数不是必需的,请求上可带可不带

12.@CrossOrigin
Cross-Origin ResourceSharing(跨域资源共享)的简写,作用是解决跨域访问的问题,在Spring4.2以上的版本可直接使用。在类上或方法上添加该注解.

13.@GetMapping、@RequestMapping和@PostMapping

@GetMapping(value = “page”)等价于@RequestMapping(value = “page”, method = RequestMethod.GET)

@PostMapping(value = “page”)等价于@RequestMapping(value = “page”, method = RequestMethod.POST)

14.@ControllerAdvice、@ExceptionHandler
@ControllerAdvice注解就是加强Controller,有这个注解的类中的方法的某些注解会应用到所有的Controller里,其中就包括@ExceptionHandler注解。
@ExceptionHandler 当一个Controller中有方法加入该注解后,这个Controller其他方法中没有捕获的异常就会以参数的形式传入加了@ExceptionHandler注解的那个方法中。

@ControllerAdvice  
public class GlobalExceptionHandler {  
    @ExceptionHandler(SQLException.class)  
    @ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR,reason=”sql查询错误”)  
    @ResponseBody  
    public ExceptionResponse handleSQLException(HttpServletRequest request, Exception ex) {  
        String message = ex.getMessage();  
        return ExceptionResponse.create(HttpStatus.INTERNAL_SERVER_ERROR.value(), message);  
    } 

上例中,@ControllerAdvance 将@ExceptionHandler注入到所有注解过@controller的类的方法中,而@ExceptionHandler注解进一步将其方法引用到所有@controller注解类的方法中,所以每一个Controller方法都可以进行所有异常的处理。


@ControllerAdvance 除了与@ExceptionHandler注解搭档之外,通常与ResponseBodyAdvice拦截Controller方法默认返回参数,统一处理返回值/响应体。这里就不详细展开

15.@RestController
@RestController = @Controller + @ResponseBody。
是2个注解的合并效果,即指定了该controller是组件,又指定方法返回的是String或json类型数据。

16.@SpringBootApplication
申明让spring boot自动给程序进行必要的配置,这个配置等同于:
@Configuration ,@EnableAutoConfiguration 和 @ComponentScan 三个配置。

@Configuration的注解类标识这个类可以使用Spring IoC容器作为bean定义的来源。@Bean注解告诉Spring,一个带有@Bean的注解方法将返回一个对象,该对象应该被注册为在Spring应用程序上下文中的bean。
@EnableAutoConfiguration:能够自动配置spring的上下文,试图猜测和配置你想要的bean类,通常会自动根据你的类路径和你的bean定义自动配置。
@ComponentScan:会自动扫描指定包下的全部标有@Component的类,并注册成bean,当然包括@Component下的子注解@Service,@Repository,@Controller。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值