Spring/Spring Boot 常用注解总结!

Spring/Spring Boot 常用注解总结!

Spring/Spring Boot 常用注解总结!

在这里插入图片描述

Web:

@Controller:组合注解(组合了@Component 注解),应用在 MVC 层(控制层)。
@RestController:该注解为一个组合注解,相当于@Controller 和@ResponseBody 的组合,注解在类上,意味着,该 Controller 的所有方法都默认加上了@ResponseBody。
@RequestMapping:用于映射 Web 请求,包括访问路径和参数。如果是 Restful 风格接口,还可以根据请求类型使用不同的注解:
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@ResponseBody:支持将返回值放在 response 内,而不是一个页面,通常用户返回 json 数据。
@RequestBody:允许 request 的参数在 request 体中,而不是在直接连接在地址后面。
@PathVariable:用于接收路径参数,比如 @RequestMapping(“/hello/{name}”)申明的路径,将注解放在参数中前,即可获取该值,通常作为 Restful 的接口实现方法。
@RestController:该注解为一个组合注解,相当于@Controller 和@ResponseBody 的组合,注解在类上,意味着,该 Controller 的所有方法都默认加上了@ResponseBody。

容器:

@Component:表示一个带注释的类是一个“组件”,成为 Spring 管理的 Bean。当使用基于注解的配置和类路径扫描时,这些类被视为自动检测的候选对象。同时@Component 还是一个元注解。
@Service:组合注解(组合了@Component 注解),应用在 service 层(业务逻辑层)。
@Repository:组合注解(组合了@Component 注解),应用在 dao 层(数据访问层)。
@Autowired:Spring 提供的工具(由 Spring 的依赖注入工具(BeanPostProcessor、BeanFactoryPostProcessor)自动注入)。
@Qualifier:该注解通常跟 @Autowired 一起使用,当想对注入的过程做更多的控制,@Qualifier 可帮助配置,比如两个以上相同类型的 Bean 时 Spring 无法抉择,用到此注解
@Configuration:声明当前类是一个配置类(相当于一个 Spring 配置的 xml 文件)
@Value:可用在字段,构造器参数跟方法参数,指定一个默认值,支持 #{} 跟 ${} 两个方式。一般将 SpringbBoot 中的 application.properties 配置的属性值赋值给变量。
@Bean:注解在方法上,声明当前方法的返回值为一个 Bean。返回的 Bean 对应的类中可以定义 init()方法和 destroy()方法,然后在@Bean(initMethod=”init”,destroyMethod=”destroy”)定义,在构造之后执行 init,在销毁之前执行 destroy。
@Scope:定义我们采用什么模式去创建 Bean(方法上,得有@Bean) 其设置类型包括:Singleton 、Prototype、Request 、 Session、GlobalSession。

AOP:

@Aspect:声明一个切面(类上) 使用@After、@Before、@Around 定义建言(advice),可直接将拦截规则(切点)作为参数。
@After :在方法执行之后执行(方法上)。
@Before: 在方法执行之前执行(方法上)。
@Around: 在方法执行之前与之后执行(方法上)。
@PointCut: 声明切点 在 java 配置类中使用@EnableAspectJAutoProxy 注解开启 Spring 对 AspectJ 代理的支持(类上)。

事务:

@Transactional:在要开启事务的方法上使用@Transactional 注解,即可声明式开启事务。

其他总结

@ConditionalOnProperty: 控制配置类@Configuration是否生效.(实现是通过havingValue与配置文件中的值对比,返回为true则配置类生效,反之失效.)

  • 配置类代码:
/**
 * @prefix prefix为配置文件中的前缀,
 * @name name为配置的名字
 * @havingValue 是与配置的值对比值,当两个值相同返回true,配置类生效.
 */
@Configuration
@ConditionalOnProperty(prefix = "filter",name = "loginFilter",havingValue = "true")
public class FilterConfig {
    @Bean
    public FilterRegistrationBean getFilterRegistration() {
        FilterRegistrationBean filterRegistration  = new FilterRegistrationBean(new LoginFilter());
        filterRegistration.addUrlPatterns("/*");
        return filterRegistration;
    }
}

  • 配置文件中的代码
filter.loginFilter=true

@ConditionalOnClass注解与@ConditionalOnProperty

@ConditionalOnClass注解作用:  某个class位于类路径上,才会实例化一个Bean。即判断当前classpath下是否存在指定类,若是则将当前的配置装载入spring容器

@ConditionalOnProperty:控制@Configuration是否生效

 Spring提供的Condition
        除了自己自定义Condition之外,Spring还提供了很多Condition给我们用

 @ConditionalOnBean         仅仅在当前上下文中存在某个对象时,才会实例化一个Bean
@ConditionalOnClass        某个class位于类路径上,才会实例化一个Bea
@ConditionalOnExpression      当表达式为true的时候,才会实例化一个Bean。
        比如:

        @ConditionalOnExpression("true")

        @ConditionalOnExpression("${my.controller.enabled:false}")

4. @ConditionalOnMissingBean 仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean

5. @ConditionalOnMissingClass 某个class类路径上不存在的时候,才会实例化一个Bean

6. @ConditionalOnNotWebApplication 不是web应用

(8)题外话:怎么在Condition中获取application.properties的配置项

       在实际开发中,我们的条件可能保存在application.properties中,那么怎么在Condition中获取呢,这个很简单,主要通过ConditionContext进行获取,具体代码如下:

Java代码 

String port = context.getEnvironment().getProperty("server.port");  
 
System.out.println(port); 

@Primary: 使用@Autowired时,当多个候选者有资格自动装配单值依赖项时,应优先考虑注解Bean。

@InitBinder: Spring可以自动封装Bean(基本数据类型(int,String等)),如果传递过来的是特殊对象,则需要手动进行封装。

Spring提供了@initBinder(初始化绑定封装)注解和WebDataBinder工具。用户只需要向WebDataBinder注册自己需要的类型的属性编辑器即可。

/*
前台传递过来的String类型时间,通过下面的初始化绑定,转换成Date类型
*/
@initBinder
public void initBinder(WebDataBinder binder){
  SimpleDateFormate sdf=new SimpleDateFormate("yyyy-MM-dd HH:mm");
  binder.registerCustomEditor(Date.class,new CustomDateEditor(sdf,true));//true表示允许空值,false不允许
}

lombok常用注解

在这里插入图片描述

@Builder: 自动生成流式 set 值写法,从此之后再也不用写一堆 setter 了

在这里插入图片描述

@Data: 加了这个注解,等于同时加了以下注解

@Getter/@Setter
@ToString
@EqualsAndHashCode
@RequiredArgsConstructor

@NoArgsConstructor, @AllArgsConstructor, @RequiredArgsConstructor

这三个都是在自动生成该类的构造器,差别只在生成的构造器的参数不一样而已

  • @NoArgsConstructor : 生成一个没有参数的构造器
  • @AllArgsConstructor : 生成一个包含所有参数的构造器
  • @RequiredArgsConstructor : 生成一个包含 final 修饰词的变量参数 的构造器, 如果所有的变量都没有用 final 修饰的 话,那就会生成一个没有参数的构造器
    在这里插入图片描述
    注意一个 Java 的小坑

@AllArgsConstructor 时,一定要补上 @NoArgsConstrcutor
(当我们没有指定构造器时,Java 编译器会帮我们自动生成一个没有任何参数的构造器给该类,但是如果我们自己写了构造器之后,Java 就不会自动帮我们补上那个无参数的构造器了)

@ConditionalOnMissingBean,它是修饰bean的一个注解,主要实现的是,当你的bean被注册之后,如果而注册相同类型的bean,就不会成功,它会保证你的bean只有一个,即你的实例只有一个,当你注册多个相同的bean时,会出现异常,以此来告诉人员。

获取接口请求中的参数

1、@PathVariable: 映射 URL 绑定的占位符, 能使传过来的参数绑定到路由上。

@RequestMapping(value = "/user/{userid}/view")  //占位符 userid
public String view ( @PathVariable("userid") String userid){ //@PathVariable 中指定 userid
    System.out.println("userid= "+userid);   //此处可以获取:userid= 031267
    return SUCCESS;
}

2、@RequestParam :获取request请求参数中的值

请求路径:http://www.test.com/user/query?username=zhangsan&age=20

@RequestMapping(value = "/user/query")
public String query(@RequestParam(value="username") String username) {	
	System.out.println("username = " + username);   //此处打印:username = zhangsan
	return SUCCESS;
}

3、@RequestBody :获取 request 请求体 body 的值

仅限用于post请求
一般情况下,@RequestBody只处理 Content-Type 是 application/json 或者 application/xml。

	@PostMapping
    public String add(@RequestBody User user)
    {
       return "";
    }

@PostConstruct是Java自带的注解
@PostConstruct注解的方法在项目启动的时候执行这个方法,也可以理解为在spring容器启动的时候执行,可作为一些数据的常规化加载,比如数据字典之类的。
执行顺序
Constructor >> @Autowired >> @PostConstruct
在这里插入图片描述

注解@SuppressWarnings()是用来忽略警告的,内部参数不同,忽略的警告不同。

@InitBinder

@InitBinder用于在@Controller中标注于方法上,表示为当前控制器注册一个属性编辑器,只对当前的Controller有效。@InitBinder标注的方法必须有一个参数WebDataBinder。所谓的属性编辑器可以理解就是帮助我们完成参数绑定。

    @ResponseBody
    @RequestMapping(value = "/test")
    public String test(@RequestParam String name,@RequestParam Date date) throws Exception {
        System.out.println(name);
        System.out.println(date);
        return name;
    }

    @InitBinder
    public void initBinder(WebDataBinder binder){
        binder.registerCustomEditor(String.class,
                new StringTrimmerEditor(true));

        binder.registerCustomEditor(Date.class,
                new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), false));

    }

上面例子中,@InitBinder方法会帮助我们把String类型的参数先trim再绑定,而对于Date类型的参数会先格式化在绑定。例如当请求是/test?name=%20zero%20&date=2018-05-22时,会把zero绑定到name,再把时间串格式化为Date类型,再绑定到date。

这里的@InitBinder方法只对当前Controller生效,要想全局生效,可以使用@ControllerAdvice。通过@ControllerAdvice可以将对于控制器的全局配置放置在同一个位置,注解了@ControllerAdvice的类的方法可以使用@ExceptionHandler,@InitBinder,@ModelAttribute注解到方法上,这对所有注解了@RequestMapping的控制器内的方法有效。

@ControllerAdvice
public class GlobalControllerAdvice {

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(String.class,
                new StringTrimmerEditor(true));

        binder.registerCustomEditor(Date.class,
                new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), false));

    }
}

除了使用@ControllerAdvice来配置全局的WebDataBinder,还可以使用RequestMappingHandlerAdapter:

    @Bean
    public RequestMappingHandlerAdapter webBindingInitializer() {
        RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter();
        adapter.setWebBindingInitializer(new WebBindingInitializer(){

            @Override
            public void initBinder(WebDataBinder binder, WebRequest request) {
                binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), false));

            }
        });
        return adapter;
    }

如上示例,可以实现同样的效果。

@ControllerAdvice中除了配置@InitBinder,还可以有@ExceptionHandler用于全局处理控制器里面的异常;@ModelAttribute作用是绑定键值对到Model里,让全局的@RequestMapping都能获得在此处设置的键值对。

补充:如果 @ExceptionHandler注解中未声明要处理的异常类型,则默认为方法参数列表中的异常类型。示例:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    String handleException(Exception e){
        return "Exception Deal! " + e.getMessage();
    }
}

其他记录

@Bean+@Qualifier(“name”)指定别名。
给每个Bean添加不同的名字:

@Configuration
@ComponentScan
public class AppConfig {
    @Bean("z")
    ZoneId createZoneOfZ() {
        return ZoneId.of("Z");
    }

    @Bean
    @Qualifier("utc8")
    ZoneId createZoneOfUTC8() {
        return ZoneId.of("UTC+08:00");

    }
}

存在多个同类型的Bean时,注入ZoneId又会报错:

NoUniqueBeanDefinitionException: No qualifying bean of type ‘java.time.ZoneId’ available: expected single matching bean but found 2
意思是期待找到唯一的ZoneId类型Bean,但是找到两。因此,注入时,要指定Bean的名称:

@Component
public class MailService {
	@Autowired(required = false)
	@Qualifier("z") // 指定注入名称为"z"的ZoneId
	ZoneId zoneId = ZoneId.systemDefault();
    ...
}
@Component
public class MailService {
    @Value("#{smtpConfig.host}")
    private String smtpHost;

    @Value("#{smtpConfig.port}")
    private int smtpPort;
}

@Component
public class SmtpConfig {
    @Value("${smtp.host}")
    private String host;

    @Value("${smtp.port:25}")
    private int port;

    public String getHost() {
        return host;
    }

    public int getPort() {
        return port;
    }
}

注意观察#{}这种注入语法,它和${key}不同的是,#{}表示从JavaBean读取属性。"#{smtpConfig.host}"的意思是,从名称为smtpConfig的Bean读取host属性,即调用getHost()方法。

Spring容器可以通过@PropertySource自动读取配置,并以@Value(“${key}”)的形式注入;

可以通过${key:defaultValue}指定默认值;

以#{bean.property}形式注入时,Spring容器自动把指定Bean的指定属性值注入。

EnableScheduling

@EnableScheduling 在配置类上使用,开启计划任务的支持(类上)

非典型结构下的初始化

那么如果,我们一定要加载非root package下的内容怎么办呢?
方法一:使用@ComponentScan注解指定具体的加载包,比如:

@SpringBootApplication
@ComponentScan(basePackages="com.example")
public class Bootstrap {

    public static void main(String[] args) {
        SpringApplication.run(Bootstrap.class, args);
    }

}

方法二:使用@Bean注解来初始化,比如:

@SpringBootApplication
public class Bootstrap {

    public static void main(String[] args) {
        SpringApplication.run(Bootstrap.class, args);
    }

    @Bean
    public CustomerController customerController() {
        return new CustomerController();
    }

}
@SpringBootApplication
public class Bootstrap {

    public static void main(String[] args) {
        SpringApplication.run(Bootstrap.class, args);
    }

    @Bean
    public CustomerController customerController() {
        return new CustomerController();
    }

}

在应用中我们可以通过@Value注解来加载这些自定义的参数,比如:

@Component
public class Book {

    @Value("${book.name}")
    private String name;
    @Value("${book.author}")
    private String author;

    // 省略getter和setter
}

@Value注解加载属性值的时候可以支持两种表达式来进行配置:

一种是我们上面介绍的PlaceHolder方式,格式为 ${…},大括号内为PlaceHolder
另外还可以使用SpEL表达式(Spring Expression Language), 格式为 #{…},大括号内为SpEL表达式

在Spring Boot 2.0中增加了新的绑定API来帮助我们更容易的获取配置信息。

假设在propertes配置中有这样一个配置:com.didispace.foo=bar

我们为它创建对应的配置类:

@Data
@ConfigurationProperties(prefix = "com.didispace")
public class FooProperties {

    private String foo;

}

接下来,通过最新的Binder就可以这样来拿配置信息了:

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(Application.class, args);

        Binder binder = Binder.get(context.getEnvironment());

        // 绑定简单配置
        FooProperties foo = binder.bind("com.didispace", Bindable.of(FooProperties.class)).get();
        System.out.println(foo.getFoo());
    }
}

Druid中各连接池配置的说明可查阅:

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值