• Spring 常用注解粗陋看法


    @Service("userService")

    spring产生一个service层bean示例,就是相当于把

    UserServiceImpl userService = new UserServiceImpl();
    

    这一步给自动化管理了。你要用的话直接引入就可以了

    @Service("userService")
    public class UserServiceImpl implements UserService {
        @Resource
        private UserMapper userMapper;
        @Override
        public User getUserById(String id) {
            return userMapper.getUserById(id);
        }
    }
    

    @Value注解使用自定义参数

    springboot application.yml 配置

    server:
      port: 80
      servlet:
        context-path:
    #自定义参数配置
    custom:
      value1: 测试参数1
      map: "{ds: '发送失败',ds3: '未发送,ds4: 发送成功'}"
      list: "test,test32"
    

    自定义参数配置类

    // 标明这是一个配置类
    @Configuration
    // lombok 实体注解
    @Data
    public class CustomVariableConfig {
        //从 application 配置文件中获取 custom.value1 的值 “测试参数1” 注入到 customValue1。
        @Value("${custom.value1:defaultValue}")//设置默认值defaultValue,如果value1没有值则使用defaultValue
        private String customValue1;
        //${}只能获取到字符串,二次加工需要搭配#{}使用
        @Value("#{${custom.map}}")
        private Map<String,String> map;
        @Value("#{'${custom.list}'.split(',')}")
        private List<String> list;
    }
    

    @ConfigurationProperties配置参数空间注解

    java类

    @Component
    // lombok 实体注解
    @Data
    //自定义参数空间,会自动扫描 custom 下的所有配置参数(默认支持驼峰转换)并尝试注入到该实体类的同名属性中。
    @ConfigurationProperties("custom")
    public class CustomVariableConfig {
        /*
        @Value("#{${custom.map}}")
        private Map<String,String> map;
        类使用ConfigurationProperties注解时失效,项目启动出错,但是该语法放入controller类下可以直接使用。
         */
    
        /**
         * 由于 已使用ConfigurationProperties注解,该 Value 注解可以忽略。
         * 而且,在ConfigurationProperties配置类下,Value注解的支持非常不友好,只支持基础类型注入,
         * 不建议混用。
         */
        @Value("${custom.customValue1}")
        private String customValue1;
    
        /**
         * 参数名默认驼峰转换 simple-view-controllers——>simpleViewControllers
         */
        private List<Map<String,String>> simpleViewControllers;
    
    }
    

    yml文件配置

    #自定义参数配置
    custom:
      customValue1: 测试参数1
      # value注解 map案例,外面的双引号可用可不用
      map: "{ds: '发送失败',ds3: '未发送,ds4: 发送成功'}"
      # value注解 list使用案例,外面的双引号可用可不用
      list1: "test,test32"
      # ConfigurationProperties注解 搭配使用案例
      #配置简单请求路径,需要搭建自己的处理器,该配置方式必须有使用 ConfigurationProperties注解 的参数配置类引入,好像不可以使用 value注解 解析
      simple-view-controllers:
        - urlParame: index
          templatePath: index
        - urlParame: forgetPsd
          templatePath: user/ordinary
        - urlParame: iregister
          templatePath: user/admin
        - urlParame: boss
          templatePath: user/boss
    

    @Autowired与@Resource的区别

    @Autowired

    1、本身无name属性,如果想通过名称匹配注入则需要配合@Qualifier注解一起使用。

    @Autowired()
    @Qualifier("userService")
    UserService userService;
    

    2、默认required为true,即叫这个名字的bean实例必须要有,不然报错。可手动设置为false,此时代码会有警告。妈蛋上传不了图片。就是下面的Qualifier注解属性会变成大红色。

        @Autowired(required = false)
        @Qualifier("userService")
        UserService userService;
    

    3、由spring提供

    @Resource

    1、name属性值设置则通过name匹配,

        @Resource(name = "userService")
        UserService userService;
        //上面这段代码必须有对应的userService,如果下面的这个实现类没有指定service名字为userService则会报错
        @Service("userService")
    	public class UserServiceImpl implements UserService {}
    

    2、name属性值未设置则先按照名字后通过类型匹配

        @Resource()
        UserService userService;
        //下面这里无论是否指定service名字都不会报错
        @Service("userService")
    	public class UserServiceImpl implements UserService {}
    

    3、由jdk1.6开始提供
    4、默认可为空
    2021.8.8补充
    从jdk11开始,移除了@Resource注解,该注解Spring家族通过引入 jakarta.annotation:jakarta.annotation-api:1.3.5 来支持该注解。
    image

    @ComponentScan

    设置 spring 扫描包路径

    //单个扫描
    @ComponentScan(basePackages = {"com.jdw.springboot.entity"})
    //多个扫描
    @ComponentScan(basePackages = {"com.jdw.springboot.*","com.jdw.springboot2.*"})
    

    用于告诉spring去哪里获取bean。spring不会再扫描所有注解的bean,而只会扫描指定的包下面的。而且这个太深了也不行。

    //正常
    @ComponentScan(basePackages = {"com.jdw.springboot.*"})
    //出错
    @ComponentScan(basePackages = {"com.*"})
    

    注意
    ‘.*’ 不能扫到下面所有,最好还是写清楚。

    //奇葩异常一:Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
    @ComponentScan(basePackages = {"com.*"})
    @MapperScan("com.jdw.springboot.mapper")
    
    //正常
    @ComponentScan(basePackages = {"com.jdw.*"})
    @MapperScan("com.jdw.springboot.mapper")
    

    @Component

    直接写在类上面,标明这个类要被 spring 管理(相当于举手,并不一定被管理。)

    @Component
    public class TimedTask {
        //标明这个方法是个定时任务
        @Scheduled(fixedRate = 2000)
        private void task1() throws Exception{
            System.out.println("2秒执行一遍定时任务");
        }
    }
    

    @Aspect 面向切面编程相关

    直接写在类上面,标明这个类是个切面类,即:
    AOP (Aspect Oriented Programming)中的 Aspect

    //标明这是一个切面类
    @Aspect
    //标明这个类由 spring 自动管理
    @Component
    public class ControllerAspect {
    	@Pointcut(value = " execution(public * com.jdw.sys.controller..*.*(..))")
        public void webLog() {
        }
        /**
         * 退出执行,final增强,不管是抛出异常或者正常退出都会执行
         */
        @After("webLog()")
        public void doAfter() {
            log.info("After");
        }
    }
    

    @Pointcut

    //  扫描controller下的所有类
    //  @Pointcut(value = "within(com.jdw.sys.controller.*)")
    //  扫描使用了 GetMapping 注解的所有类
    //  @Pointcut(value = "@annotation(org.springframework.web.bind.annotation.GetMapping)")
    //  扫描 com.jdw.sys.controller 下的类及其下面子包内的类 的 访问修饰符为 public 方法(public可以不设置,则扫描所有)
    //  修饰方法,声明一个切面对象,切面名字是方法名 "webLog()" 具体切面是 value 值设置
        @Pointcut(value = " execution(public * com.jdw.sys.controller..*.*(..))")
        public void webLog() {
        }
    

    2020.08.01补充:
    spring 切面的思想是面向类切面,所以内部方法之间的调用时不会触发切面的。
    失败案例:

    @RestController
    @RequestMapping("/demo")
    public class DemoController {
        @GetMapping("/test")
        public String test(){
            return test1();
        }
        public String test1(){
            return "fdsdfs";
        }
    }
    
    
    @Aspect
    //标明这个类由 spring 自动管理
    @Component
    //引用 lombok 的 log
    @Slf4j
    public class ControllerAspect {
        //设置切面
    //    扫描类
    //    @Pointcut(value = "within(com.jdw.sys.controller.*)")
    //    扫描注解
    //    @Pointcut(value = "@annotation(org.springframework.web.bind.annotation.GetMapping)")
    //    扫描 com.jdw.sys.controller 下的类及其下面子包内的类 的 访问修饰符为 public 方法(public可以不设置,则扫描所有)
        @Pointcut(value = " execution(public * com.jdw.sys.controller..*.test1(..))")
        public void webLog() {
        }
    

    @Before

    //方法执行前执行
        @Before("webLog()")
        public void doBefor(JoinPoint joinPoint) {
            //接受请求,记录请求内容
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            //打印请求内容
            log.info("URL:" + request.getRequestURI());
            log.info("HTTP_METHOD:" + request.getMethod());
    //        log.info("IP:"+request.getRemoteAddr());
    //        log.info("HOST:"+request.getRemoteHost());
    //        log.info("PORT:"+request.getRemotePort());
            Enumeration<String> parameterNames = request.getParameterNames();
            log.info("请求参数列表为:");
            while (parameterNames.hasMoreElements()) {
                String s = parameterNames.nextElement();
                log.info(s + ":" + request.getParameter(s));
            }
        }
    

    @After

        /**
         * 退出执行,final增强,不管是抛出异常或者正常退出都会执行
         */
        @After("webLog()")
        public void doAfter() {
            log.info("After");
        }
    

    @AfterReturning

        /**
         * 方法正常退出时执行,在 @After 后面执行
         */
        @AfterReturning(returning = "object", pointcut = "webLog()")
        public void doAfterReturning(Object object) {
            log.info("RESPONSE:" + object);
        }
    

    @AfterThrowing

        /**
         * 抛出异常执行,在 @After 后面执行
         */
        @AfterThrowing(value = "webLog()", throwing = "exception")
        public void doAfterThrowing(JoinPoint joinPoint, Exception exception) {
            log.info(joinPoint.getSignature().getName() + "抛出异常:" + exception.getMessage());
        }
    

    @Around

    2020.08。01补充:
    ProceedingJoinPoint(程序连接点)类的几个实用方法,

    Object[] getArgs:返回目标方法的参数
    
    Signature getSignature:返回目标方法的签名
    
    Object getTarget:返回被织入增强处理的目标对象
    
    Object getThis:返回AOP框架为目标对象生成的代理对象
    
        /**
         * 环绕通知:
         * 环绕通知非常强大,可以决定目标方法是否执行,什么时候执行,执行时是否需要替换方法参数,执行完毕是否需要替换返回值。
         * 环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型
         * 如过环绕通知决定不执行目标方法,则其他切面注解定义的处理都不会执行.
         */
        @Around("webLog()")
        public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
            log.info("- - - - - 环绕通知 - - - -");
            log.info("环绕通知的目标方法名:" + proceedingJoinPoint.getSignature().getName());
            try {//obj之前可以写目标方法执行前的逻辑
    //            log.info("执行目标方法前执行");
                Object obj = proceedingJoinPoint.proceed();//调用执行目标方法
                return obj;//返回目标方法返回值
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            } finally {
                log.info("- - - - - 环绕通知 end - - - -");
            }
            return null;
        }
    

    @EnableScheduling+@Scheduled 集成定时任务

    springboot的定时任务超简单,两个注解搞定。

    @EnableScheduling

    启动类添加 @EnableScheduling 注解,开启定时任务。

    @SpringBootApplication
    //springboot 设置 component 扫描路径
    @ComponentScan(basePackages = {"com.jdw.*.*"})
    //springboot 设置 mapper 扫描路径
    @MapperScan("com.jdw.*.mapper")
    //springboot 开启定时任务
    @EnableScheduling
    public class SpringbootApplication {
        public static void main(String[] args) {
            SpringApplication.run(SpringbootApplication.class, args);
        }
    }
    

    bean类 方法上添加 @Scheduled 注解,标明这个方法是一个定时任务。

    //交给 spring 管理
    @Component
    public class TimedTask {
        private static int t = 0;
    //    标明这个方法是个定时任务,每两秒创建一个等待上一个完成后执行。
    //    上一个执行完毕,新的立即执行。
    //    上一个未执行完毕,新的不会执行,如果上一个的执行时间超过了两秒,则上一个执行完毕后,新的立即执行。
    //    @Scheduled(fixedRate = 2000L)
    
    //    标明这个方法是个定时任务,上一个定时任务完成后2秒新建定时任务开始执行。
    //    @Scheduled(fixedDelay = 2000L)
    
    //    标明这个方法是个定时任务,每四秒钟判断上一个是否已执行,上一个执行完毕则新建定时任务开始执行。未执行完毕则等待4秒后继续判断
        @Scheduled(cron = "0/4 * * * * ?")
        private void task1() throws Exception{
            t++;
            System.out.println("task"+t+":定时任务开始"+(new Date()).getTime());
            Thread.sleep(2000);
    //        System.out.println("task1:定时任务休眠完成"+(new Date()).getTime());
        }
    }
    
    

    @Lazy懒加载注解

    @Controller
    @RequestMapping("/gcjs/bszn")
    public class GcjsBsznController {
        @Autowired
        //当被调用时 spring 执行构造器构造对象。如果没有该注解,则是当该类实例被创建时执行构造器构造对象。
        @Lazy
        private ICCfgTypeService cCfgTypeService;
        }
    

    @RequestBody 请求体注解

    //使用@RequestBody注解,自动将请求体转对象时需注意。
    //接收对象类型,要么使用fast.Json接收,要么使用自定义vo对象或bean对象接收。
    //经测试,当我们需要将请求体转为bean对象时,sf.json、hutool.json、jackson对于枚举属性的转换很不友好。
    @PostMapping("test")
    @RequestBody
    public object test(@RequestBody Object object){
    	return object;
    }
    

    @JsonFormat对象转json时变量转换规则

    	//该案例代表,当将该对象以json返回给前端时,时间会转换为"yyyy-MM-dd HH:mm:ss"格式的字符串
       @JsonFormat(timezone = "GMT+8", pattern= "yyyy-MM-dd HH:mm:ss")
       private LocalDateTime updateTime;
    

    @DateTimeFormat json字符串转对象时变量转换规则

    	//该案例代表,当直接以对象接收入参时,会将updateTime字符串值以"yyyy-MM-dd HH:mm:ss"格式转换为LocalDateTime类型
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime updateTime;
    

    @SpringBootTest

    @ActiveProfiles("native")

    /**
     * @Author ListJiang
     * @Since 1.0.1
     * datetime 2021/7/1 13:30
     */
    // 声明这是一个springboot项目测试
    @SpringBootTest
    // 指定测试运行环境
    @ActiveProfiles("native")
    public class DemoWebTest {
        @Test
        void contextLoads() {
            String t = "[ tt ts]";
            String substring = t.substring(1, t.length() - 1);
            System.out.println(substring);
        }
    }
    

    @ConditionalOnProperty

    // 声明一个配置类,当存在spring.profile.active配置的属性值包含dev的时候生效
    @Configuration
    @ConditionalOnProperty(prefix = "spring.profile", name = "active", havingValue = "dev")
    public class RestTemplateConfig {
    }
    
  • 相关阅读:
    ovs tag
    从数据库分析OpenStack创建虚机流程
    Neutron中的二层网络服务架构
    Failed to bind port
    OpenStack网络参数segment
    OpenStack与SDN控制器的集成
    HDU 3709 Balanced Number
    HDU 5787 K-wolf Number
    HDU 5803 Zhu’s Math Problem
    CodeForces 258B Little Elephant and Elections
  • 原文地址:https://www.cnblogs.com/jiangdewen/p/15115144.html
Copyright © 2020-2023  润新知