寻一处小筑,不遇车马喧嚣;
聚一帮好友,丢下城市烦恼;
忘情于山水,醉卧于诗画;
昨晚的篝火,照亮远方;
湖面的月关,透着清凉;
最美的时光,是你已住进我的心房;
SpringBoot提供了很多注解,可以帮助我们快速构建应用程序。以下是SpringBoot最常用的250个注解;
(1)@SpringBootApplication
作用:这是一个组合注解
包括了@Configuration、@EnableAutoConfiguration和@ComponentScan三个注解。
用于标识SpringBoot应用程序的入口类。
@Configuration:指示这个类是一个配置类,它定义了一个或多个@Bean方法,用于创建和配置Spring应用程序上下文中的Bean。
@EnableAutoConfiguration:启用Spring?Boot的自动配置机制,它会自动添加所需的依赖项和配置,以使应用程序能够运行。
@ComponentScan:指示Spring Boot扫描当前包及其子包中的所有@Component、@Service、@Repository和@Controller注解的类,并将它们注册为Spring Bean。
@SpringBootApplication注解通常被用于Spring Boot应用程序的入口类上,用于启动Spring Boot应用程序。它可以简化Spring应用程序的配置和启动过程。
(2)@RestController
作用:与@Controller类似,但是@RestController会自动将返回值转换为JSON格式。
@RestController是Spring Framework 4.0版本引入的一个注解,它是@Controller和@ResponseBody的组合注解。它用于标注一个类,表示这个类是一个RESTful风格的控制器,可以处理HTTP请求并返回JSON/XML格式的响应。
@RestController注解用于替代原来的@Controller注解,它默认情况下会将控制器方法的返回值转换为JSON格式,并以HTTP响应的方式返回给客户端。如果需要返回XML格式的响应,可以使用其他注解,如@Produces和@Consumes。
(3)@RequestMapping
作用:用于映射请求URL和处理方法。@RequestMapping是Spring MVC框架中的一个核心注解,它用于映射HTTP请求和控制器方法之间的关系。它可以用于类级别和方法级别,用于指定请求URL和HTTP方法(GET、POST、PUT、DELETE等)。
(4)@GetMapping
作用:用于映射HTTP GET请求。
@RestController
@RequestMapping("/api")
public class PesonController {
?
? ? @GetMapping("/persons")
? ? public List<Peson> getPesons() {
? ? ? ? // 获取用户列表
? ? }
?
? ? @GetMapping("/pesons/{id}")
? ? public Peson getPesonById(@PathVariable Long id) {
? ? ? ? // 根据ID获取用户信息
? ? }
}
(5)@PostMapping
作用:用于映射HTTP POST请求。
@RestController
@RequestMapping("/api")
public class PersonController {
?
? ? @PostMapping("/person")
? ? public void createPerson(@RequestBody Person person) {
? ? ? ? // 创建新用户
? ? }
}
?(6)@PutMapping
作用:用于映射HTTP PUT请求。
@RestController
@RequestMapping("/api")
public class PesonController {
?
? ? @PutMapping("/Pesons/{id}")
? ? public void updatePeson(@PathVariable Long id, @RequestBody Peson?person) {
? ? ? ? // 更新用户信息
? ? }
}
(7)@DeleteMapping
作用:用于映射HTTP DELETE请求。
@RestController
@RequestMapping("/api")
public class PersonController {
?
? ? @PutMapping("/persons/{id}")
? ? public void updatePerson(@PathVariable Long id, @RequestBody User user) {
? ? ? ? // 更新用户信息
? ? }
}?
(8)@RequestParam
作用:用于获取请求参数的值。
@RestController
@RequestMapping("/api")
public class PersonController {
?
? ? @GetMapping("/Persons")
? ? public List<Person> getPersons(@RequestParam("page") int page, @RequestParam("size") int size) {
? ? ? ? // 分页获取用户列表
? ? }
}
(9)@PathVariable
作用:用于获取URL中的参数值。@PathVariable是Spring MVC框架中的一个注解,用于将HTTP请求路径中的变量绑定到控制器方法的参数上。
@RestController
@RequestMapping("/api")
public class PersonController {
?
? ? @GetMapping("/persons/{id}")
? ? public Person getPerson(@PathVariable Long id) {
? ? ? ? // 根据ID获取用户信息
? ? }
}?
(10)@RequestBody
作用:用于将HTTP请求的主体转换为方法的参数。@RequestBody是Spring MVC框架中的一个注解,用于将HTTP请求体中的数据绑定到控制器方法的参数上。
@RestController
@RequestMapping("/api")
public class PersonController {
?
? ? @PostMapping("/persons")
? ? public Person createPerson(@RequestBody Person person) {
? ? ? ? // 创建用户
? ? }
}?
(11)@ResponseBody
作用:用于将方法的返回值转换为HTTP响应的主体。@ResponseBody是Spring MVC框架中的一个注解,用于将控制器方法的返回值转换为HTTP响应体中的数据。
@RestController
@RequestMapping("/api")
public class PersonController {
?
? ? @GetMapping("/persons/{id}")
? ? public Person getPerson(@PathVariable Long id) {
? ? ? ? // 根据ID获取用户信息
? ? }
}?
(12)@Autowired
作用:用于自动装配Spring容器中的Bean。
@Service
public class PersonServiceImpl implements PersonService {
?
? ? @Autowired
? ? private PersonRepository personRepository;
?
? ? // 实现PersonService接口中的方法
}?
(13)@Component
作用:用于标识一个类是Spring容器中的组件。@Component是Spring框架中的一个通用注解,用于标注一个类作为Spring Bean。
@Component
public class PersonServiceImpl implements PersonService {
?
? ? // 实现PersonService接口中的方法
}?
(14)@Service
作用:用于标识一个类是Spring容器中的服务组件。@Service是Spring框架中的一个注解,用于标注一个类作为服务类(Service)。
@Service
public class PersonServiceImpl implements PersonService {
?
? ? // 实现PersonService接口中的方法
}?
(15)@Repository
作用:用于标识一个类是Spring容器中的数据访问组件。@Repository是Spring框架中的一个注解,用于标注一个类作为数据访问对象(DAO)。
@Repository
public class PersonRepositoryImpl implements PersonRepository {
?
? ? // 实现PersonRepository接口中的方法
}?
(16)@Configuration
作用:用于标识一个类是Spring的配置类。@Configuration是Spring框架中的一个注解,用于标注一个类作为配置类。
@Configuration
public class AppConfig {
?
? ? @Bean
? ? public PersonService personService() {
? ? ? ? return new PersonServiceImpl();
? ? }
?
? ? @Bean
? ? public PersonRepository personRepository() {
? ? ? ? return new PersonRepositoryImpl();
? ? }
}
(17)@Value
作用:用于获取配置文件中的属性值。@Value是Spring框架中的一个注解,用于将配置文件中的属性值注入到Bean对象中。
@Component
public class PersonComponent {
?
? ? @Value("${my.property}")
? ? private String myProperty;
?
? ? // 其他方法
}?
(18)@Bean
作用:用于将一个方法返回的对象注册到Spring容器中。@Bean是Spring框架中的一个注解,用于将一个方法返回的对象注册为一个Spring Bean。
@Configuration
public class AppConfig {
?
? ? @Bean
? ? public PersonService personSService() {
? ? ? ? return new PersonSServiceImpl();
? ? }
?
? ? @Bean
? ? public PersonSRepository personSRepository() {
? ? ? ? return new PersonSRepositoryImpl();
? ? }
}?
(19)@Import
作用:用于导入其他配置类或Bean。
@Configuration
@Import({AppConfig1.class, AppConfig2.class})
public class AppConfig {
?
? ? // 其他方法
}?
(20)@Conditional
作用:用于根据条件判断是否创建Bean或执行配置。
@Configuration
public class AppConfig {
?
? ? @Bean
? ? @Conditional(DatabaseTypeCondition.class)
? ? public PersonRepository personRepository() {
? ? ? ? return new PersonRepositoryImpl();
? ? }
?
? ? // 其他方法
}?
(21)@Profile
作用:用于指定配置的环境,如开发环境、测试环境或生产环境。
@Configuration
public class AppConfig {
?
? ? @Bean
? ? @Profile("dev")
? ? public PersonService personServiceDev() {
? ? ? ? return new PersonServiceDevImpl();
? ? }
?
? ? @Bean
? ? @Profile("prod")
? ? public PersonService personServiceProd() {
? ? ? ? return new PersonServiceProdImpl();
? ? }
?
? ? // 其他方法
}?
(22)@PropertySource
作用:用于指定配置文件的位置。@PropertySource是Spring框架中的一个注解,用于指定一组属性文件的位置,从而可以在Spring应用程序中使用这些属性。
@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig {
?
? ? @Autowired
? ? private Environment environment;
?
? ? @Bean
? ? public PersonService personService() {
? ? ? ? return new PersonServiceImpl(environment.getProperty("personService.name"));
? ? }
?
? ? // 其他方法
}?
这个类使用@Configuration注解标注,表示这个类是一个配置类,用于配置应用程序的Bean对象。
在类级别上,使用@PropertySource注解可以指定一个属性文件的位置。在这个例子中,使用@PropertySource注解指定了一个名为application.properties的属性文件,它位于classpath下。
在方法级别上,使用@Bean注解标注方法,表示这个方法返回一个Bean对象。在这个例子中,使用Environment对象从属性文件中读取属性值,并将这些属性值传递给PersonService实例的构造方法。
@PropertySource注解用于指定一组属性文件的位置,使得开发者可以在Spring应用程序中使用这些属性。同时,使用Environment对象可以方便地读取属性文件中的属性值,并将这些属性值传递给Bean对象的构造方法或属性。
@PropertySource注解是Spring框架中比较常用的注解之一,可以让开发者更加灵活地管理和配置Spring Bean。
(23)@Qualifier
作用:用于指定注入的Bean的名称。
@Component
public class PersonServiceImpl implements PersonService {
?
? ? @Autowired
? ? @Qualifier("PersonRepositoryImpl")
? ? private PersonRepository personRepository;
?
? ? // 其他方法
}?
(24)@ExceptionHandler
作用:用于处理异常。
@ControllerAdvice
public class GlobalExceptionHandler {
?
? ? @ExceptionHandler(Exception.class)
? ? public ModelAndView handleException(Exception ex) {
? ? ? ? ModelAndView modelAndView = new ModelAndView();
? ? ? ? modelAndView.addObject("errorMessage", ex.getMessage());
? ? ? ? modelAndView.setViewName("error");
? ? ? ? return modelAndView;
? ? }
}
这个类使用@ControllerAdvice注解标注,表示这个类是一个全局异常处理器。在方法级别上,使用@ExceptionHandler注解可以指定一个方法来处理控制器中抛出的异常。
在这个例子中,使用@ExceptionHandler注解指定了一个名为handleException的方法,它处理所有类型的异常。当控制器中抛出异常时,会调用这个方法,并将异常对象作为参数传递给这个方法。
在这个方法中,使用ModelAndView对象来封装错误信息,并将视图名称设置为error。最后,返回这个ModelAndView对象,将错误信息显示到用户界面上。
@ExceptionHandler注解用于处理控制器中抛出的异常,使得开发者可以根据需要灵活地处理异常。同时,使用@ControllerAdvice注解可以将这个异常处理器应用于所有的控制器中。
@ExceptionHandler注解是Spring框架中比较常用的注解之一,可以让开发者更加灵活地处理控制器中的异常。
(25)@ResponseStatus
作用:用于指定异常的HTTP响应状态码。
@Controller
public class PersonController {
?
? ? @GetMapping("/person/{id}")
? ? @ResponseBody
? ? @ResponseStatus(HttpStatus.OK)
? ? public PersonDetails getPersonDetails(@PathVariable("id") Long id) {
? ? ? ? // 查询用户信息
? ? ? ? PersonDetails personDetails = personService.getPersonDetails(id);
? ? ? ? if (personDetails == null) {
? ? ? ? ? ? throw new PersonNotFoundException("Person not found");
? ? ? ? }
? ? ? ? return personDetails;
? ? }
?
? ? @ExceptionHandler(PersonNotFoundException.class)
? ? @ResponseStatus(HttpStatus.NOT_FOUND)
? ? @ResponseBody
? ? public String handlePersonNotFoundException(PersonNotFoundException ex) {
? ? ? ? return ex.getMessage();
? ? }
}
(26)@ControllerAdvice
作用:用于全局拦截处理。
@ControllerAdvice是Spring框架中的一个注解,用于定义全局控制器通知。
在Spring MVC框架中,控制器通知是一些特殊的组件,它们可以在控制器方法执行前、执行后或抛出异常时执行一些额外的逻辑处理。使用@ControllerAdvice注解可以定义全局控制器通知,它可以应用于所有的控制器。
@ControllerAdvice
public class GlobalControllerAdvice {
?
? ? @ModelAttribute("currentPerson")
? ? public Person?getCurrentPerson() {
? ? ? ? // 获取当前登录用户信息
? ? ? ? Person currentPerson = personService.getCurrentPerson();
? ? ? ? return currentPerson;
? ? }
?
? ? @InitBinder
? ? public void initBinder(WebDataBinder binder) {
? ? ? ? // 注册自定义的属性编辑器
? ? ? ? binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
? ? }
?
? ? @ExceptionHandler(Exception.class)
? ? public ModelAndView handleException(Exception ex) {
? ? ? ? ModelAndView modelAndView = new ModelAndView();
? ? ? ? modelAndView.addObject("errorMessage", ex.getMessage());
? ? ? ? modelAndView.setViewName("error");
? ? ? ? return modelAndView;
? ? }
}?
(27)@CrossOrigin
作用:用于解决跨域问题。
@CrossOrigin是Spring框架中的一个注解,用于解决跨域资源共享(CORS)问题。
跨域资源共享是浏览器安全策略的一部分,它限制了浏览器在不同域名之间发送和接收HTTP请求。使用@CrossOrigin注解可以指定允许跨域访问的域名和HTTP方法。
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "http://localhost:8080", methods = {RequestMethod.GET, RequestMethod.POST})
public class ApiController {
?
? ? @GetMapping("/persons")
? ? public List<Person> getPerson() {
? ? ? ? // 查询用户信息
? ? ? ? List<Person> persons?= personService.getPersons();
? ? ? ? return persons?;
? ? }
}?
这个类使用@RestController注解标注,表示这个类是一个RESTful风格的控制器。在类级别上,使用@RequestMapping注解指定控制器处理的请求路径为/api。同时,使用@CrossOrigin注解可以指定允许跨域访问的域名和HTTP方法。
在这个例子中,使用@CrossOrigin注解指定允许来自http://localhost:8080域名的GET和POST请求访问该控制器中的方法。这意味着,在http://localhost:8080域名下的网页可以通过XMLHttpRequest对象发送GET和POST请求,访问该控制器中的方法。
@CrossOrigin注解用于解决跨域资源共享(CORS)问题,使得开发者可以更加灵活地控制允许跨域访问的域名和HTTP方法。它是一种简单但非常有效的解决方案,可以使得前端开发者更加轻松地开发跨域应用程序。
@CrossOrigin注解是Spring框架中比较常用的注解之一,可以让开发者更加灵活地解决跨域资源共享(CORS)问题。
?
(28)@Async
作用:用于将方法标记为异步执行。
在Spring框架中,如果一个方法需要执行一些比较耗时的操作,如果这个方法是在主线程中执行,就会导致主线程被阻塞,用户界面无法响应用户的操作。使用@Async注解可以将这个方法的执行异步化,让主线程继续执行其他任务,提高应用程序的响应性能。
@Service
public class PersonService {
?
? ? @Async
? ? public CompletableFuture<PersonDetails> getPersonDetailsAsync(Long id) {
? ? ? ? // 查询用户信息
? ? ? ? PersonDetails personDetails = personRepository.getPersonDetails(id);
? ? ? ? return CompletableFuture.completedFuture(personDetails);
? ? }
}
这个类使用@Service注解标注,表示这个类是一个服务。在方法级别上,使用@Async注解标注方法,表示这个方法需要异步执行。
在这个例子中,getPersonDetailsAsync方法使用@Async注解标注,表示这个方法需要异步执行。查询用户信息的操作在异步线程中执行,不会阻塞主线程。同时,这个方法返回一个CompletableFuture对象,表示异步执行的结果。
@Async注解用于异步执行方法,可以提高应用程序的响应性能。它是一种简单但非常有效的解决方案,可以使得开发者更加轻松地编写并发应用程序。
@Async注解是Spring框架中比较常用的注解之一,可以让开发者更加灵活地异步执行方法。需要注意的是,异步执行的方法必须在一个独立的线程中执行,因此需要使用线程池来管理异步线程的执行。
(29)@Cacheable
作用:用于缓存方法的返回值。
在Spring框架中,如果一个方法的返回结果是固定的,而且这个方法的执行比较耗时,我们可以使用@Cacheable注解将这个方法的返回结果缓存起来,下次执行这个方法时直接从缓存中获取结果,避免重复执行。
@Service
public class PersonService {
?
? ? @Cacheable("PersonCache")
? ? public Person getPerson(Long id) {
? ? ? ? // 查询用户信息
? ? ? ? Person person = PersonRepository.getPerson(id);
? ? ? ? return person ;
? ? }
}
这个类使用@Service注解标注,表示这个类是一个服务。在方法级别上,使用@Cacheable注解标注方法,表示这个方法返回的结果可以被缓存起来。
在这个例子中,getPerson方法使用@Cacheable注解标注,表示这个方法的返回结果可以被缓存起来。查询用户信息的操作在第一次执行时会被执行,返回结果会被缓存到名为"personCache"的缓存中。下次执行getPerson方法时,如果缓存中已经存在这个结果,就直接从缓存中获取结果,不需要再次执行查询操作。
@Cacheable注解用于缓存方法的返回结果,可以提高应用程序的执行效率。它是一种简单但非常有效的解决方案,可以使得开发者更加灵活地使用缓存来优化应用程序的性能。
@Cacheable注解是Spring框架中比较常用的注解之一,可以让开发者更加轻松地使用缓存来提高应用程序的性能。需要注意的是,使用缓存需要考虑缓存的生命周期和缓存的一致性,必要时需要使用缓存失效机制和缓存更新机制来维护缓存的一致性。
(30)@CacheEvict
作用:用于清除缓存。
@CacheEvict是Spring框架中的一个注解,用于清空缓存中的数据。
在Spring框架中,如果一个方法的执行会导致缓存数据的失效,我们可以使用@CacheEvict注解将这个方法的缓存数据清空,这样下次执行这个方法时就会重新查询数据并缓存起来。
@Service
public class PersonService {
?
? ? @Cacheable("personCache")
? ? public Person getPerson(Long id) {
? ? ? ? // 查询用户信息
? ? ? ? Person person= personRepository.getPerson(id);
? ? ? ? return person;
? ? }
? ??
? ? @CacheEvict("personCache")
? ? public void clearCache() {
? ? ? ? // 清空缓存
? ? }
}?
这个类使用@Service注解标注,表示这个类是一个服务。在方法级别上,使用@Cacheable注解标注getPerson方法,表示这个方法的返回结果可以被缓存起来。同时,使用@CacheEvict注解标注clearCache方法,表示这个方法会清空名为"personCache"的缓存。
在这个例子中,getPerson方法使用@Cacheable注解标注,表示这个方法的返回结果可以被缓存起来。查询用户信息的操作在第一次执行时会被执行,返回结果会被缓存到名为"personCache"的缓存中。下次执行getPerson方法时,如果缓存中已经存在这个结果,就直接从缓存中获取结果,不需要再次执行查询操作。
当调用clearCache方法时,@CacheEvict注解会清空名为"personCache"的缓存,下次执行getPerson方法时,就需要重新查询数据并缓存起来。
@CacheEvict注解用于清空缓存中的数据,可以使得开发者更加灵活地控制缓存的生命周期和缓存的一致性。它是一种简单但非常有效的解决方案,可以使得开发者更加轻松地使用缓存来提高应用程序的性能。
@CacheEvict注解是Spring框架中比较常用的注解之一,可以让开发者更加灵活地控制缓存的生命周期和缓存的一致性。需要注意的是,清空缓存需要谨慎操作,必要时需要考虑缓存的失效机制和缓存更新机制来维护缓存的一致性。
(31)@CachePut
作用:用于更新缓存中的数据。
@CachePut是Spring框架中的一个注解,用于更新或添加缓存中的数据。
在Spring框架中,如果一个方法的执行会导致缓存数据的更新或添加,我们可以使用@CachePut注解将这个方法的返回结果更新或添加到缓存中。
@Service
public class PersonService {
?
? ? @Cacheable("personCache")
? ? public Person getPerson(Long id) {
? ? ? ? // 查询用户信息
? ? ? ? Person person= personRepository.getPerson(id);
? ? ? ? return person;
? ? }
? ??
? ? @CachePut("personCache")
? ? public Person updatePerson(Long id, Person person) {
? ? ? ? // 更新用户信息
? ? ? ? Person updatedPerson = personRepository.updatedPerson (id, person);
? ? ? ? return updatedPerson ;
? ? }
}?
这个类使用@Service注解标注,表示这个类是一个服务。在方法级别上,使用@Cacheable注解标注getPerson 方法,表示这个方法的返回结果可以被缓存起来。同时,使用@CachePut注解标注updatePerson 方法,表示这个方法会更新或添加名为"personCache"的缓存。
在这个例子中,getPerson 方法使用@Cacheable注解标注,表示这个方法的返回结果可以被缓存起来。查询用户信息的操作在第一次执行时会被执行,返回结果会被缓存到名为"personCache"的缓存中。下次执行getPerson方法时,如果缓存中已经存在这个结果,就直接从缓存中获取结果,不需要再次执行查询操作。
当调用updatePerson 方法时,@CachePut注解会更新或添加名为"personCache"的缓存,下次执行getPerson 方法时,就可以从缓存中获取更新后的用户信息。
@CachePut注解用于更新或添加缓存中的数据,可以使得开发者更加灵活地控制缓存的生命周期和缓存的一致性。它是一种简单但非常有效的解决方案,可以使得开发者更加轻松地使用缓存来提高应用程序的性能。
@CachePut注解是Spring框架中比较常用的注解之一,可以让开发者更加灵活地控制缓存的生命周期和缓存的一致性。需要注意的是,更新或添加缓存需要谨慎操作,必要时需要考虑缓存的失效机制和缓存更新机制来维护缓存的一致性。
(32)@Transactional
作用:用于启用事务管理功能。
@Transactional是Spring框架中的一个注解,用于标识一个方法或类需要使用事务进行操作。
在Spring框架中,如果一个方法需要对数据库进行操作,我们可以使用@Transactional注解来确保这个操作在一个事务中进行,从而保证操作的原子性、一致性、隔离性和持久性。
@Service
@Transactional
public class PersonService {
?
? ? @Autowired
? ? private PersonRepository personRepository;
?
? ? public void createPerson(Person person) {
? ? ? ? personRepository.save(person);
? ? }
? ??
? ? public void updatePerson(Long id, Person person) {
? ? ? ? Person existingPerson= personRepository.findById(id);
? ? ? ??
? ? ? ? if (existingPerson != null) {
? ? ? ? ? ? existingPerson.setName(person.getName());
? ? ? ? ? ? existingPerson.setEmail(person.getEmail());
? ? ? ? ? ? personRepository.save(existingPerson);
? ? ? ? }
? ? }
}?
这个类使用@Service注解标注,表示这个类是一个服务。同时,在类级别上使用@Transactional注解标注,表示这个类中的所有方法都需要使用事务进行操作。
在这个例子中,createPerson和updatePerson方法都需要对数据库进行操作,因此使用personRepository来保存或更新用户信息。由于这个类使用了@Transactional注解来标识,因此personRepository的操作都在一个事务中进行,从而保证操作的原子性、一致性、隔离性和持久性。
@Transactional注解用于标识一个方法或类需要使用事务进行操作,可以使得开发者更加灵活地控制事务的使用。它是一种简单但非常有效的解决方案,可以使得开发者更加轻松地使用事务来提高应用程序的性能和数据一致性。
@Transactional注解是Spring框架中比较常用的注解之一,可以让开发者更加灵活地控制事务的使用。需要注意的是,事务的使用需要谨慎操作,必要时需要考虑事务的隔离级别、超时时间和回滚机制等来维护数据的一致性和应用程序的性能。
(33)@EnableAspectJAutoProxy
作用:用于启用AOP功能。
@EnableAspectJAutoProxy是Spring框架中的一个注解,用于启用自动代理功能,以便使用AOP(面向切面编程)进行编程。
在Spring框架中,如果需要使用AOP来实现某些功能,我们可以使用@EnableAspectJAutoProxy注解来启用自动代理功能,从而在运行时自动为我们生成代理对象,以便进行切面编程。
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
?
? ? @Bean
? ? public DemoAspect demoAspect() {
? ? ? ? return new DemoAspect();
? ? }
? ??
? ? @Bean
? ? public PersonService personService() {
? ? ? ? return new PersonService();
? ? }
}?
这个类使用@Configuration注解标注,表示这个类是一个配置类。同时,在类级别上使用@EnableAspectJAutoProxy注解标注,表示这个配置类需要启用自动代理功能。
在这个例子中,我们定义了一个DemoAspect类来实现某些功能的切面编程。为了让Spring框架能够自动为我们生成代理对象,我们需要将DemoAspect类加入到Spring容器中,并且使用@Bean注解标注。另外,我们还定义了一个PersonService类来实现某些业务功能。
@EnableAspectJAutoProxy注解用于启用自动代理功能,可以使得开发者更加方便地使用AOP来实现某些功能。它是一种简单但非常有效的解决方案,可以让开发者更加轻松地使用切面编程来提高应用程序的性能和可维护性。
@EnableAspectJAutoProxy注解是Spring框架中比较常用的注解之一,可以让开发者更加方便地使用AOP来实现某些功能。需要注意的是,AOP的使用需要谨慎操作,必要时需要考虑AOP的切面逻辑、切入点和通知类型等来维护应用程序的性能和可维护性。
?(34)@Aspect
作用:用于定义切面。
@Aspect是Spring框架中的一个注解,用于标识一个类为切面类,从而可以在该类中定义切面逻辑以实现AOP(面向切面编程)。
在Spring框架中,如果需要使用AOP来实现某些功能,我们可以使用@Aspect注解来标识一个类为切面类。在切面类中,我们可以定义切面逻辑,包括切入点、通知类型和切面顺序等,从而实现AOP编程的功能
@Aspect
@Component
public class DemoAspect {
?
? ? @Before("execution(* com.example.PersonService.*(..))")
? ? public void beforeAdvice() {
? ? ? ? System.out.println("Before advice is executed.");
? ? }
? ??
? ? @After("execution(* com.example.PersonService.*(..))")
? ? public void afterAdvice() {
? ? ? ? System.out.println("After advice is executed.");
? ? }
}
这个类使用@Aspect注解标识,表示这个类是一个切面类。同时,我们还使用@Component注解标识这个类,以便Spring框架能够自动将它加入到Spring容器中。
在这个例子中,我们定义了一个DemoAspect类来实现某些功能的切面编程。在这个类中,我们定义了两个通知类型,即@Before和@After,分别表示在目标方法执行前和执行后执行某些操作。这些通知类型的执行条件是通过切入点表达式来定义的。
@Aspect注解用于标识一个类为切面类,可以使得开发者更加方便地使用AOP来实现某些功能。它是一种简单但非常有效的解决方案,可以让开发者更加轻松地使用切面编程来提高应用程序的性能和可维护性。
@Aspect注解是Spring框架中比较常用的注解之一,用于标识一个类为切面类。需要注意的是,AOP的使用需要谨慎操作,必要时需要考虑切入点、通知类型和切面顺序等来维护应用程序的性能和可维护性。
(35)@Pointcut
作用:用于定义切点。
@Pointcut是Spring框架中的一个注解,用于定义一个切入点,从而可以在该切入点上定义通知类型以实现AOP(面向切面编程)。
在Spring框架中,如果需要使用AOP来实现某些功能,我们可以使用@Pointcut注解来定义一个切入点。在切入点上,我们可以定义切面逻辑,包括通知类型和切面顺序等,从而实现AOP编程的功能。
@Aspect
@Component
public class DemoAspect {
?
? ? @Pointcut("execution(* com.example.PersonService.*(..))")
? ? public void personServicePointcut() {}
? ??
? ? @Before("personServicePointcut()")
? ? public void beforeAdvice() {
? ? ? ? System.out.println("Before advice is executed.");
? ? }
? ??
? ? @After("personServicePointcut()")
? ? public void afterAdvice() {
? ? ? ? System.out.println("After advice is executed.");
? ? }
}?
这个类使用@Aspect注解标识,表示这个类是一个切面类。同时,我们还使用@Component注解标识这个类,以便Spring框架能够自动将它加入到Spring容器中。
在这个例子中,我们定义了一个MyAspect类来实现某些功能的切面编程。在这个类中,我们使用@Pointcut注解定义了一个切入点,即personServicePointcut()方法。在这个切入点上,我们定义了两个通知类型,即@Before和@After,分别表示在目标方法执行前和执行后执行某些操作。
@Pointcut注解用于定义一个切入点,可以使得开发者更加方便地使用AOP来实现某些功能。它是一种简单但非常有效的解决方案,可以让开发者更加轻松地使用切面编程来提高应用程序的性能和可维护性。
@Pointcut注解是Spring框架中比较常用的注解之一,用于定义一个切入点。需要注意的是,AOP的使用需要谨慎操作,必要时需要考虑切入点、通知类型和切面顺序等来维护应用程序的性能和可维护性。
(36)@Before
作用:用于在方法执行前执行通知。
@Before是Spring框架中的一个注解,用于定义在目标方法执行前执行的通知类型,以实现AOP(面向切面编程)。
在Spring框架中,如果需要在目标方法执行前执行某些操作,我们可以使用@Before注解来定义一个通知类型。在这个通知类型中,我们可以编写自己的逻辑代码,从而实现AOP编程的功能。
@Aspect
@Component
public class DemoAspect {
?
? ? @Before("execution(* com.example.PersonService.*(..))")
? ? public void beforeAdvice() {
? ? ? ? System.out.println("Before advice is executed.");
? ? }
}?
(37)@After
作用:用于在方法执行后执行通知。
@After是Spring框架中的一个注解,用于定义在目标方法执行后执行的通知类型,以实现AOP(面向切面编程)。
在Spring框架中,如果需要在目标方法执行后执行某些操作,我们可以使用@After注解来定义一个通知类型。在这个通知类型中,我们可以编写自己的逻辑代码,从而实现AOP编程的功能。
@Aspect
@Component
public class DemoAspect {
?
? ? @After("execution(* com.example.PersonService.*(..))")
? ? public void afterAdvice() {
? ? ? ? System.out.println("After advice is executed.");
? ? }
}?
(38)@Around
作用:用于在方法执行前后执行通知。
@Around是Spring框架中的一个注解,用于定义在目标方法执行前后执行的通知类型,以实现AOP(面向切面编程)。
在Spring框架中,如果需要在目标方法执行前后执行某些操作,我们可以使用@Around注解来定义一个通知类型。在这个通知类型中,我们可以编写自己的逻辑代码,从而实现AOP编程的功能。
@Aspect
@Component
public class DemoAspect {
?
? ? @Around("execution(* com.example.PersonService.*(..))")
? ? public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
? ? ? ? System.out.println("Before advice is executed.");
? ? ? ? Object result = joinPoint.proceed();
? ? ? ? System.out.println("After advice is executed.");
? ? ? ? return result;
? ? }
}?
(39)@AfterReturning
作用:用于在方法返回结果后执行通知。
@AfterReturning是Spring框架中的一个注解,用于定义在目标方法返回结果后执行的通知类型,以实现AOP(面向切面编程)。
在Spring框架中,如果需要在目标方法返回结果后执行某些操作,我们可以使用@AfterReturning注解来定义一个通知类型。在这个通知类型中,我们可以编写自己的逻辑代码,从而实现AOP编程的功能。
@Aspect
@Component
public class DemoAspect {
?
? ? @AfterReturning(pointcut = "execution(* com.example.PersonService.*(..))", returning = "result")
? ? public void afterReturningAdvice(Object result) {
? ? ? ? System.out.println("After returning advice is executed. Result is " + result);
? ? }
}?
(40)@AfterThrowing
作用:用于在方法抛出异常后执行通知。
@AfterThrowing是Spring框架中的一个注解,用于定义在目标方法抛出异常后执行的通知类型,以实现AOP(面向切面编程)。
在Spring框架中,如果需要在目标方法抛出异常后执行某些操作,我们可以使用@AfterThrowing注解来定义一个通知类型。在这个通知类型中,我们可以编写自己的逻辑代码,从而实现AOP编程的功能。
@Aspect
@Component
public class DemoAspect {
?
? ? @AfterThrowing(pointcut = "execution(* com.example.PersonService.*(..))", throwing = "ex")
? ? public void afterThrowingAdvice(Exception ex) {
? ? ? ? System.out.println("After throwing advice is executed. Exception is " + ex);
? ? }
}
(41)@RequestHeader
把Request请求header部分的值绑定到方法的参数上
1. 获取单个请求头
例如,获取 user-id 请求头
@RequestMapping("/getSingleHeader")
public Map<String, Object> getSingleHeader(@RequestHeader("user-id") String userId){
? ? ? ? Map<String, Object> result = new HashMap<>();
? ? ? ? result.put("code", 0);
? ? ? ? result.put("msg", "success");
? ? ? ? result.put("userId", userId);
? ? ? ? return result;
}
2. 一次性获取所有请求头
方式一:使用 Map 接收所有请求头
@RequestMapping("/getAllHeaders")
public Map<String, Object> listAllHeaders(@RequestHeader Map<String, String> headers) {
? ? ? ? Map<String, Object> result = new HashMap<>();
? ? ? ? headers.forEach((key, value) -> {
? ? ? ? ? ? // 日志中输出所有请求头
? ? ? ? ? ? System.out.println(String.format("Header '%s' = %s", key, value));
? ? ? ? });
? ? ? ? result.put("code", 0);
? ? ? ? result.put("msg", "success");
? ? ? ? result.put("headers", headers);
? ? ? ? ?return result;
}
方式二:使用 MultiValueMap 接收所有请求头
@RequestMapping("/listHeaders")
public Map<String, Object> listHeaders(@RequestHeader MultiValueMap<String, String> headers) {
? ? ? ? Map<String, Object> result = new HashMap<>();
? ? ? ? headers.forEach((key, value) -> {
? ? ? ? ? ? ?// 日志中输出所有请求头
? ? ? ? ? ? System.out.println(String.format("Header '%s' = %s", key, value));
? ? ? ? });
? ? ? ? result.put("code", 0);
? ? ? ? result.put("msg", "success");
? ? ? ? result.put("headers", headers);
? ? ? ? return result;
}
方式三:使用 HttpHeaders 接收所用请求头
@RequestMapping("/getAllHttpHeaders")
public Map<String, Object> getAllHttpHeaders(@RequestHeader HttpHeaders headers) {
? ? ? ? headers.forEach((key, value) -> {
? ? ? ? ? ? ?// 日志中输出所有请求头
? ? ? ? ? ? System.out.println(String.format("getAllHttpHeaders '%s' = %s", key, value));
? ? ? ? });
? ? ? ? Map<String, Object> result = new HashMap<>();
? ? ? ? result.put("code", 0);
? ? ? ? result.put("msg", "success");
? ? ? ? result.put("headers", headers);
? ? ? ? return result;
}
查看 HttpHeaders 源码发现 MultiValueMap<String, String>
如果在项目中需要接收多个请求,使用 MultiValueMap 和 HttpHeaders 的选择,可以节省参数个数,使得代码整洁;当然,如果就接受一两个请求头,直接使用 RequestHeader ?注解就可以。
?
(42)@CookieValue
以前在 Servlet 中获取某个指定的 Cookie 的值时,使用Cookie[] cookies=request.getCookies();来获得所有 Cookie 的值,然后再遍历。把Request header中关于cookie的值绑定到方法的参数上
?@RequestMapping("/springmvc")
@Controller
public class HelloWorld {
@RequestMapping("/testCookieValue")
? ? public String testCookieValue(@CookieValue("JSESSIONID")String sessionId){
? ? ? ? System.out.println("testCookieValue: "+sessionId);
? ? ? ? return "success";
? ? }
}
(43)@Order
作用:用于指定切面的执行顺序。
@Order是Spring框架中的一个注解,用于定义切面的执行顺序。在Spring框架中,如果有多个切面类需要对同一个方法进行切面处理,那么这些切面类的执行顺序可能会影响到最终的结果。为了控制这些切面类的执行顺序,我们可以使用@Order注解来定义它们的执行顺序。
@Order注解可以应用在切面类上,用于指定切面执行的顺序。它的参数为一个整数,数值越小表示优先级越高,数值相同时按照类名的自然顺序进行排序。
@Aspect
@Component
@Order(1)
public class DemoAspectOne?{
?
? ? @Before("execution(* com.example.PersonService.*(..))")
? ? public void beforeAdvice() {
? ? ? ? System.out.println("Before advice from DemoAspectOne?is executed.");
? ? }
}
?
@Aspect
@Component
@Order(2)
public class DemoAspectTwo?{
?
? ? @Before("execution(* com.example.PersonService.*(..))")
? ? public void beforeAdvice() {
? ? ? ? System.out.println("Before advice from DemoAspectTwo?is executed.");
? ? }
}
(44)@Slf4j
作用:用于简化日志记录。
@Slf4j是Lombok框架中的一个注解,用于在Java类中自动生成日志记录器。
在Java开发中,日志记录是非常重要的一环,可以帮助我们更好地了解程序的运行情况,从而更好地进行调试和优化。通常情况下,我们需要手动引入日志框架(如Log4j、SLF4J等)并编写相应的日志记录代码。这些代码可能会比较繁琐,而且容易出现错误。为了简化这个过程,Lombok框架提供了一个@Slf4j注解,可以在Java类中自动生成日志记录器。
使用@Slf4j注解非常简单,只需要在Java类中添加这个注解即可。在使用时,我们可以直接使用log变量来记录日志,而不需要再引入其他的日志框架
@Slf4j
public class DemoService {
?
? ? public void doSomething() {
? ? ? ? log.debug("This is a debug message.");
? ? ? ? log.info("This is an info message.");
? ? ? ? log.error("This is an error message.");
? ? }
}?
在这个例子中,我们定义了一个DemoService类,并使用@Slf4j注解来自动生成日志记录器。然后,在doSomething()方法中,我们直接使用log变量来记录日志,而不需要再引入其他的日志框架。
需要注意的是,使用@Slf4j注解需要在编译器中安装Lombok插件,否则可能会出现编译错误。另外,虽然@Slf4j注解非常方便,但在实际应用中,我们还需要根据实际情况选择合适的日志框架,并编写相应的日志记录代码。
总之,@Slf4j是Lombok框架中的一个注解,可以在Java类中自动生成日志记录器,从而简化日志记录的过程。它是一种极为方便的解决方案,可以提高应用程序的可维护性和可读性。
(45)@Data?
作用:用于自动生成JavaBean的getters、setters、toString、hashCode和equals方法。
@Data是Lombok框架中的一个注解,可以自动生成Java类的getter、setter、equals、hashCode和toString等方法。
在Java开发中,我们经常需要编写一些POJO类来表示数据结构。这些类通常包含一些成员变量,并且需要编写相应的getter、setter、equals、hashCode和toString等方法。这些方法通常是相似的,而且比较繁琐。为了简化这个过程,Lombok框架提供了一个@Data注解,可以自动生成这些方法。
使用@Data注解非常简单,只需要在Java类上添加这个注解即可。在使用时,我们可以直接访问类的成员变量,并且可以自动生成相应的getter、setter、equals、hashCode和toString等方法。
@Data
public class Person {
? ? private Long personId;
? ? private String personName;
? ? private Integer personAge;
}
(46)@NoArgsConstructor?
作用:用于生成无参构造函数。
@NoArgsConstructor是Lombok框架中的一个注解,用于自动生成一个无参构造方法。
在Java开发中,我们经常需要编写一些POJO类来表示数据结构。这些类通常包含一些成员变量,并且需要编写相应的构造方法。在某些情况下,我们可能需要编写一个无参构造方法,用于创建一个对象的实例。这个构造方法通常是简单的、无需参数的。为了简化这个过程,Lombok框架提供了一个@NoArgsConstructor注解,可以自动生成一个无参构造方法。
使用@NoArgsConstructor注解非常简单,只需要在Java类上添加这个注解即可。在使用时,我们可以直接创建对象的实例,而不需要手动编写无参构造方法。
@NoArgsConstructor
public class Person {
? ? private Long personId;
? ? private String personName;
? ? private Integer personAge;
}
在这个例子中,我们定义了一个User类,并使用@NoArgsConstructor注解来自动生成一个无参构造方法。然后,在其他的Java类中,我们可以直接创建Person对象的实例,而不需要手动编写无参构造方法。
需要注意的是,使用@NoArgsConstructor注解需要在编译器中安装Lombok插件,否则可能会出现编译错误。另外,虽然@NoArgsConstructor注解非常方便,但在实际应用中,我们还需要根据实际情况选择合适的构造方法,并编写相应的代码。
总之,@NoArgsConstructor是Lombok框架中的一个注解,用于自动生成一个无参构造方法,从而简化Java开发的过程。它是一种极为方便的解决方案,可以提高应用程序的可维护性和可读性。
?(47)@AllArgsConstructor
作用:用于生成全参构造函数。
@AllArgsConstructor是Lombok框架中的一个注解,用于自动生成一个全参构造方法。
在Java开发中,我们经常需要编写一些POJO类来表示数据结构。这些类通常包含一些成员变量,并且需要编写相应的构造方法。在某些情况下,我们可能需要编写一个全参构造方法,用于初始化所有成员变量。这个构造方法通常包含所有成员变量作为参数。为了简化这个过程,Lombok框架提供了一个@AllArgsConstructor注解,可以自动生成一个全参构造方法。
使用@AllArgsConstructor注解非常简单,只需要在Java类上添加这个注解即可。在使用时,我们可以直接创建对象的实例,并传入相应的参数,而不需要手动编写全参构造方法。
@AllArgsConstructor
public class Person {
? ? private Long personId;
? ? private String personName;
? ? private Integer personAge;
}
在这个例子中,我们定义了一个Person 类,并使用@AllArgsConstructor注解来自动生成一个全参构造方法。然后,在其他的Java类中,我们可以直接创建Person 对象的实例,并传入相应的参数,而不需要手动编写全参构造方法。
需要注意的是,使用@AllArgsConstructor注解需要在编译器中安装Lombok插件,否则可能会出现编译错误。另外,虽然@AllArgsConstructor注解非常方便,但在实际应用中,我们还需要根据实际情况选择合适的构造方法,并编写相应的代码。
总之,@AllArgsConstructor是Lombok框架中的一个注解,用于自动生成一个全参构造方法,从而简化Java开发的过程。它是一种极为方便的解决方案,可以提高应用程序的可维护性和可读性。
(48)@Builder?
作用:用于生成Builder模式的构造函数。
@Builder是Lombok框架中的一个注解,用于自动生成一个Builder模式的构造器。
在Java开发中,我们经常需要编写一些POJO类来表示数据结构。这些类通常包含一些成员变量,并且需要编写相应的构造方法。在某些情况下,我们可能需要编写一个Builder模式的构造器,用于方便地创建对象实例。Builder模式是一种创建对象的设计模式,它可以通过链式调用的方式设置对象的属性,并最终创建一个不可变的对象。为了简化这个过程,Lombok框架提供了一个@Builder注解,可以自动生成一个Builder模式的构造器。
使用@Builder注解非常简单,只需要在Java类上添加这个注解即可。在使用时,我们可以使用链式调用的方式设置对象的属性,并最终创建一个不可变的对象。
@Builder
public class Person {
? ? private Long personId;
? ? private String personName;
? ? private Integer personAge;
}
在这个例子中,我们定义了一个Person 类,并使用@Builder注解来自动生成一个Builder模式的构造器。然后,在其他的Java类中,我们可以使用链式调用的方式设置Person 对象的属性,并最终创建一个不可变的对象。
需要注意的是,使用@Builder注解需要在编译器中安装Lombok插件,否则可能会出现编译错误。另外,虽然@Builder注解非常方便,但在实际应用中,我们还需要根据实际情况选择合适的构造方法,并编写相应的代码。
总之,@Builder是Lombok框架中的一个注解,用于自动生成一个Builder模式的构造器,从而简化Java开发的过程。它是一种极为方便的解决方案,可以提高应用程序的可维护性和可读性。
(49)@EqualsAndHashCode?
作用:用于生成hashCode和equals方法。
@EqualsAndHashCode是Lombok框架中的一个注解,用于自动生成equals()和hashCode()方法。
在Java开发中,我们经常需要比较两个对象是否相等,并且需要根据对象的属性生成一个hashCode值。为了简化这个过程,Lombok框架提供了一个@EqualsAndHashCode注解,可以自动生成equals()和hashCode()方法。
使用@EqualsAndHashCode注解非常简单,只需要在Java类上添加这个注解即可。在使用时,Lombok会根据类的属性自动生成equals()和hashCode()方法。如果两个对象的所有属性都相等,那么它们的equals()方法返回true,并且它们的hashCode()方法返回相同的值。
@EqualsAndHashCode
public class Person {
? ? private Long personId;
? ? private String personName;
? ? private Integer personAge;
}
(50)@ToString?
作用:用于生成toString方法。
@ToString是Lombok框架中的一个注解,用于自动生成toString()方法。
在Java开发中,我们经常需要将对象转换为字符串,以便于输出或日志记录。为了简化这个过程,Lombok框架提供了一个@ToString注解,可以自动生成toString()方法。
使用@ToString注解非常简单,只需要在Java类上添加这个注解即可。在使用时,Lombok会根据类的属性自动生成toString()方法,这个方法将输出类的名称和所有属性的名称和值。如果需要排除某些属性,可以使用exclude属性来指定排除的属性。
@ToString(exclude = "personPassword")
public class Person {
? ? private Long personId;
? ? private String personName;
? ? private Integer personAge;? ? private String personPassword;
}
(51)@Getter?
作用:用于生成getters方法。
@Getter是Lombok框架中的一个注解,用于自动生成getter方法。
在Java开发中,我们经常需要为类的属性编写getter和setter方法。为了简化这个过程,Lombok框架提供了一个@Getter注解,可以自动生成getter方法。
使用@Getter注解非常简单,只需要在Java类上添加这个注解即可。在使用时,Lombok会根据类的属性自动生成对应的getter方法。如果需要生成setter方法,可以使用@Setter注解。
@Getter
public class Person {
? ? private Long personId;
? ? private String personName;
? ? private Integer personAge;? ? private String personPassword;
}
(52)@ConfigurationProperties
作用:将配置文件值注入到JavaBean对应属性
Spring Boot 中使用的是
.properties
?和?.yml
?两个格式的配置文件。下面就来介绍:Spring Boot 配置文件中的值,如何注入到我们自定义的 Java Bean 中。
(或者:Java Bean 如何获取配置文件中的值来注入
JavaBean类
?
package org.jd.auth.data.security.server.properties; import org.springframework.boot.context.properties.ConfigurationProperties; /** * 属性配置类 */ @ConfigurationProperties(prefix = "short.msg") // 通过该注解来进行对应属性的装配 public class ShortMessageProperties { // 访问发送短信的url地址 private String Url; // 短信服务商提供的请求keyId private String accessKeyId; // 短信服务提供商KeySecret private String accessKeySecret; public String getUrl() { return Url; } public void setUrl(String url) { Url = url; } public String getAccessKeyId() { return accessKeyId; } public void setAccessKeyId(String accessKeyId) { this.accessKeyId = accessKeyId; } public String getAccessKeySecret() { return accessKeySecret; } public void setAccessKeySecret(String accessKeySecret) { this.accessKeySecret = accessKeySecret; } }
yml 配置文件值注入
application.yml配置文件:
# 短信服务配置 short: msg: enabled: true Url: www.lingcaibao.com accessKeyId: 123456emsces accessKeySecret: 86384638433484863483
在Java Bean 类上,添加 @ConfigurationProperties(prefix = “short.msg”)注解;
在 pom.xml 中,导入配置文件处理器依赖。以后编写yml、properties配置文件,这些配置项就会有相对应的提示了。
?
<!--导入配置文件处理器,配置文件进行绑定就会有提示--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <version>2.2.6.RELEASE</version> <optional>true</optional> </dependency>
解析:
@ConfigurationProperties注解功能;
然后clean install后会在jar包中看到spring-autoconfigure-metadata.json的配置文件,该文件是自动编译生成的,内容如下:
@ConfigurationProperties 注解:它会告诉 Spring Boot 将本类中的所有属性和配置文件中相关的配置进行绑定;prefix = "short.msg":告诉 Spring Boot 应该读取配置文件中哪个下面的所有属性进行一一映射;
?
{ "groups": [ { "name": "short.msg", "type": "org.jd.auth.data.security.server.properties.ShortMessageProperties", "sourceType": "org.jd.auth.data.security.server.properties.ShortMessageProperties" } ], "properties": [ { "name": "short.msg.access-key-id", "type": "java.lang.String", "sourceType": "org.jd.auth.data.security.server.properties.ShortMessageProperties" }, { "name": "short.msg.access-key-secret", "type": "java.lang.String", "sourceType": "org.jd.auth.data.security.server.properties.ShortMessageProperties" }, { "name": "short.msg.url", "type": "java.lang.String", "sourceType": "org.jd.auth.data.security.server.properties.ShortMessageProperties" } ], "hints": [] }
(53)@ConditionalOnClass?
只有在classpath路径下能找到被该注解标注的类才会构建和实例化。源代码如下:
package org.springframework.boot.autoconfigure.condition; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.context.annotation.Conditional; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Conditional({OnClassCondition.class}) public @interface ConditionalOnClass { Class<?>[] value() default {}; String[] name() default {}; }
而该注解是一个组合注解,本身被@Conditional(条件注解匹配器)注解标注,来看看该注解中的属性OnClassCondition类的核心方法:
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { ClassLoader classLoader = context.getClassLoader(); ConditionMessage matchMessage = ConditionMessage.empty(); List<String> onClasses = this.getCandidates(metadata, ConditionalOnClass.class); List onMissingClasses; if (onClasses != null) { onMissingClasses = this.filter(onClasses, ClassNameFilter.MISSING, classLoader); if (!onMissingClasses.isEmpty()) { return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnClass.class, new Object[0]).didNotFind("required class", "required classes").items(Style.QUOTE, onMissingClasses)); } matchMessage = matchMessage.andCondition(ConditionalOnClass.class, new Object[0]).found("required class", "required classes").items(Style.QUOTE, this.filter(onClasses, ClassNameFilter.PRESENT, classLoader)); } onMissingClasses = this.getCandidates(metadata, ConditionalOnMissingClass.class); if (onMissingClasses != null) { List<String> present = this.filter(onMissingClasses, ClassNameFilter.PRESENT, classLoader); if (!present.isEmpty()) { return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnMissingClass.class, new Object[0]).found("unwanted class", "unwanted classes").items(Style.QUOTE, present)); } matchMessage = matchMessage.andCondition(ConditionalOnMissingClass.class, new Object[0]).didNotFind("unwanted class", "unwanted classes").items(Style.QUOTE, this.filter(onMissingClasses, ClassNameFilter.MISSING, classLoader)); } return ConditionOutcome.match(matchMessage); }该方法会解析被ConditionalOnClass注解标记的类,进行系列判断后,返回匹配结果,从而根据匹配结果是否实例化该类,也即是是否把该类注册为IOC容器管理的Bean;