spring常用注解anotation和@Conditional

bean注入相关注解

  • @Configuration:标注在类上,相当于把该类作为spring的xml配置文件中的,配置spring容器(应用上下文),其实就是替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器;
  • @Bean:注解用于创建一个Bean对象,然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中;
  • @component:作用于类上,把java class实例化到spring容器中
  • @Import:用来导入其他配置类;
  • @ImportResource:用来加载xml配置文件;
  • @Value:注入Spring boot application.properties配置的属性的值,写法如下:
    @Value("${env}")
    public String env;

web服务分层使用注解

  • @controller:作用于对外提供访问请求的web服务的交互类上,用于标注控制层
  • @service:用于标注服务层,主要用来进行业务的逻辑处理
  • @repository:用于标注数据访问层,也可以说用于标注数据访问组件,即DAO组件
  • @RestController:@ResponseBody和@Controller的合集

Controller层交互注解

  • @RequestMapping:作用于类或者方法上,表示该控制器可以处理的UR L请求路径;
    用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。该注解有六个属性:
    params:指定request中必须包含某些参数值是,才让该方法处理。
    headers:指定request中必须包含某些指定的header值,才能让该方法处理请求。
    value:指定请求的实际地址,指定的地址可以是URI Template 模式
    method:指定请求的method类型, GET、POST、PUT、DELETE等
    consumes:指定处理请求的提交内容类型(Content-Type),如application/json,text/html;
    produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
  • @PostMapping:指定method为POST的RequestMapping,作用和RequestMapping类似,只是指定请求类型为post;
  • @GetMapping:指定method为GET的RequestMapping;
  • @RequestParam:接收的参数是来自HTTP请求url的QueryString中;
  • @RequestBody:接收的参数是来自requestBody中,即请求体HttpEntity中的;
  • @PathVariable:接收请求路径中占位符的值

注入bean相关注解

  • @Autowired:自动导入依赖的bean,只按照byType 注入
  • @Resource:默认按byName自动注入,也提供按照byType 注入
相同点:

@Resource的作用相当于@Autowired,均可标注在字段或属性的setter方法上。

不同点:

(1)提供方:@Autowired是由org.springframework.beans.factory.annotation.Autowired提供,换句话说就是由Spring提供;@Resource是由javax.annotation.Resource提供,即J2EE提供,需要JDK1.6及以上。

(2)注入方式:@Autowired只按照byType 注入;@Resource默认按byName自动注入,也提供按照byType 注入;

(3)属性:@Autowired按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。@Resource有两个中重要的属性:name和type。name属性指定byName,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。需要注意的是,@Resource如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。

Conditional相关注解

所有conditional开头的注解,底层依赖的都是@Conditional注解,@Condition来指定满足一定条件下注册组件对像,所有的条件必须实现Condition或者SpringBootCondition接口,重写匹配计算方法,来决定组件是否注册。
在这里插入图片描述
在这里插入图片描述

  • @ConditionalOnClass:某个class位于类路径上(实际就是引入class依赖的jar包),才会实例化这个Bean,比如下面mybatis的启动类,依赖SqlSessionFactory.class,和SqlSessionFactoryBean.class,其实就是我们必须引入org.mybatis->mybatis才能生效;
@org.springframework.context.annotation.Configuration
@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
@ConditionalOnBean(DataSource.class)
@EnableConfigurationProperties(MybatisProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisAutoConfiguration {
  • @ConditionalOnBean:仅仅在当前上下文中存在某个对象时,才会实例化一个Bean;
    spring ioc的过程中,优先解析@Component,@Service,@Controller注解的类。其次解析配置类,也就是@Configuration标注的类。最后开始解析配置类中定义的bean;。但是,同样的配置类或者自定义bean的加载顺序是无法保证的,如果单纯使用ConditionalOnBean,很可能发生依赖的bean确实有,但是注入失败的情况,所以这个注解一般结合AutoConfigureBefore或者AutoConfigureAfter使用;
  • @ConditionalOnMissingBean:当前上下文中不存在某个对象时,才会实例化一个Bean,与ConditionalOnBean是相反的
  • @AutoConfiguteAfter:它的value 是一个class数组,表示在加载value里面的配置类之后再加载当前类,对比上面mybatis的配置类,就是必须先加载DataSourceAutoConfiguration才会加载MybatisAutoConfiguration。这里一定要注意,因为spring只对spring.factories文件下的配置类进行排序,所以这个注解的使用需要将加载类放到META_INF/pring.factories中;
  • @AutoConfigureBefore:和AutoConfiguteAfter基本相同,这个表示加载value里面的配置类之前先加载当前类;
  • @AutoConfigureOrder:它的value是一个int,代表优先级,执行优先级别根据数字决定,数字越小,越优先加载,负数也可以;
  • @ConditionalOnExpression:当表达式为true的时候,才会实例化一个Bean;
  • @ConditionalOnNotWebApplication:不是web应用才会加载实例化一个Bean;
  • @ConditionalOnProperty:当配置文件包含某个属性或者某个prefix开头的属性的时候才加载这个类;

全局异常处理注解

@ControllerAdvice:定义在类上,可以进行统一异常捕获和处理;
@RestControllerAdvice:@ControllerAdvice 和 @ResponseBody;
@ExceptionHandler(Exception.class):用在方法上面,捕获对应的异常,并执行对应方法;

使用@RestControllerAdvice和@ExceptionHandler实现一个统一的异常捕获和处理类,使用这个机制,可以在做一些参数验证或者服务抛错的时候,无需try catch并识别类型再进行对应的response返回对象的封装,可以直接抛出自定义的异常,直接返回给前端

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 参数数值校验失败或参数缺失导致抛出的异常
     *
     * @param req http请求信息
     * @param e   exception信息
     * @return 出错信息
     */
    @ExceptionHandler({
            MissingServletRequestParameterException.class, // 必需参数缺失
            IllegalArgumentException.class // 参数值校验失败
    })
    public Response missingServletRequestParameterExceptionHandler(HttpServletRequest req,
                                                                   Exception e
    ) {
        log.error("{} occurs: {}, msg: {}, url: {}", e.getClass(), e, e.getMessage(), req.getRequestURL());
        return Response.fail(null, ResultCode.INVALID_PARAMETER, e.getMessage());
    }

    /**
     * 参数类型错误导致抛出的异常
     *
     * @param req http请求信息
     * @param e   exception信息
     * @return 出错信息
     */
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public Response httpMessageNotReadableExceptionHandler(
            HttpServletRequest req,
            HttpMessageNotReadableException e
    ) {
        log.error("{} occurs: {}, msg: {}, url: {}", e.getClass(), e, e.getMessage(), req.getRequestURL());
        return Response.fail(null, ResultCode.INVALID_PARAMETER, ResultMsg.INVALID_PARAMETER);
    }


    /**
     * 参数类型错误导致抛出的异常
     *
     * @param req http请求信息
     * @param e   exception信息
     * @return 出错信息
     */
    @ExceptionHandler({UserException.class})
    public Response userExceptionHandler(
            HttpServletRequest req, UserException e
    ) {
        return Response.fail(null, e.getCode(), e.getMessage());
    }

    /**
     * 用于兜底的普通exception处理
     *
     * @param req http请求信息
     * @param e   exception信息
     * @return 出错信息
     */
    @ExceptionHandler({Exception.class})
    public Response exceptionHandler(HttpServletRequest req, Exception e) {
        log.error("Unknown exception occurs. class: {}, msg: {}, url: {}",
                e.getClass(), e.getMessage(), req.getRequestURL());
        // 打印堆栈信息
        StackTraceElement[] ses = e.getStackTrace();
        StringBuilder stackInfo = new StringBuilder();
        for (int i = 0, len = ses.length; i < len; i++) {
            stackInfo.append(ses[i].toString());
            if (i < len - 1) {
                stackInfo.append("\nat ");
            }
        }
        log.error("errmsg:{}", e.getMessage());
        log.error("stack trace: {}", stackInfo.toString());
        return Response.fail(null, ResultCode.INTERNAL_ERROR, ResultMsg.INTERNAL_ERROR);
    }
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值