JavaWeb注解整理——基础

学习记录,仅作参考。

一、作用

Java注解是一种强大的元数据机制,可以用来增强代码的可读性减少重复代码、简化配置等。它们的实现依赖于Java的反射机制和编译时的注解处理器,能够在编译时或运行时提供有用的信息和功能,但并不直接影响代码的逻辑执行。注解有多种用途,主要包括以下几个方面:

1.编译器指令

注解可以向编译器提供信息,帮助它在编译时进行检查。如@Override,@Deprecated。

2.编译时和运行时处理

注解可以在编译时或者运行时被工具或框架处理,用来生成代码、配置依赖注入、配置框架行为等。例如:依赖注入(@Autowired);JPA(Java Persistence API)使用注解(如@Entity、@Table)来配置实体类和数据库表之间的映射关系。

3.代码文档

注解可以用于生成代码文档(如JavaDoc),提供额外的文档信息。例如:
@author:指定类或方法的作者。
@version:指定类或方法的版本。

二、实现原理

注解的实现依托于Java的反射机制(用于在运行时动态地获取和处理注解。许多框架(如Spring)利用反射机制来实现依赖注入、AOP等功能)和编译时的注解处理器(Annotation Processor,在编译期间处理注解,生成代码或进行其他处理。注解处理器在编译阶段扫描源代码中的注解,进行相应的处理)。具体实现步骤如下:

1. 定义注解

注解通过@interface关键字定义,例如:

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
    String value();
}

@Retention:指定注解的生命周期(如RUNTIME表示运行时可用)。
@Target:指定注解可以应用的元素(如METHOD表示可以应用于方法上)。

2. 使用注解

在代码中使用自定义的注解,例如:

public class MyClass {
    @MyAnnotation("example")
    public void myMethod() {
        // 方法实现
    }
}

3.注解处理

通过反射或注解处理器来处理注解,主要是自主完成,无需我们实现。例如:

import java.lang.reflect.Method;

public class AnnotationProcessor {
    public static void main(String[] args) {
        for (Method method : MyClass.class.getDeclaredMethods()) {
            if (method.isAnnotationPresent(MyAnnotation.class)) {
                MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
                System.out.println("Method: " + method.getName() + ", Annotation Value: " + annotation.value());
            }
        }
    }
}

在这个示例中,反射机制允许我们在运行时检查MyClass中的方法是否带有@MyAnnotation注解,并获取注解的值。这种动态获取和处理注解信息的方式广泛用于框架中,例如Spring的依赖注入和AOP功能。

4.编译时注解处理器

在编译期间处理注解,生成代码或进行其他处理。注解处理器在编译阶段扫描源代码中的注解,进行相应的处理。

三、Bean对象的生成注解

@EnableAutoConfiguration

用于启用Spring Boot的自动配置功能,自动配置是根据项目类路径中的jar依赖、Bean定义和属性配置来判断需要配置的Bean。

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

@ComponentScan

  • 使用四大注解声明的bean(@Component、@Service、@Repository和@Controller)要想生效,还需要被组件扫描注解@ComponentScan扫描。
  • @ComponentScan注解虽然没有显式配置,但是实际上已经包含在了引导类声明注解 @SpringBootApplication 中,默认扫描的范围是SpringBoot启动类所在包及其子包
@Configuration
@ComponentScan(basePackages = "com.example.project")
public class AppConfig {
    // 配置类内容
}

@Import

用于导入其他配置类,使其定义的Bean也成为当前Spring应用上下文的一部分。

@Configuration
@Import(OtherConfig.class)
public class AppConfig {
    // 配置类内容
}

@PropertySource

用于指定属性文件的位置,这些属性文件可以用于配置Bean属性。

@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig {
    @Value("${my.property}")
    private String myProperty;
}

@Configuration

该注解在Spring框架中用于标记一个类作为配置类,它相当于一个传统的XML配置文件,主要用于定义和配置Bean。被@Configuration注解标记的类通常包含一个或多个被@Bean注解标记的方法,这些方法会返回需要注册到Spring应用上下文中的Bean。

@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }

    @Bean
    public MyRepository myRepository() {
        return new MyRepositoryImpl();
    }
}

在这个示例中,AppConfig类被标记为一个配置类,其中的myService和myRepository方法被标记为Bean定义方法。这些方法返回的对象将被Spring容器管理,类似于在XML配置文件中定义Bean。


@Primary

在Spring框架中用于解决当有多个相同类型的Bean可供注入时,默认使用哪个Bean的问题。它标记一个Bean为主要候选者,在没有明确指定要注入哪个Bean时,Spring会优先选择带有@Primary注解的Bean。

public interface MyService {
    void performService();
}

@Component
public class ServiceA implements MyService {
    @Override
    public void performService() {
        System.out.println("ServiceA");
    }
}

@Component
@Primary
public class ServiceB implements MyService {
    @Override
    public void performService() {
        System.out.println("ServiceB");
    }
}


三、类注解

@RestController

@RestController = @Controller + @ResponseBody 。在使用Spring框架时,“@RestController”标记在类上,用于简化创建RESTful web服务的过程。

作用:

1)控制器定义@RestController 是一个组合注解,它包括了 @Controller@ResponseBody。这意味着该注解所标记的类是一个控制器,Spring会将其注册为一个Bean,并能够接收Web请求,各方法返回结果均可直接写在HTTP响应体上。

2)自动序列化:与 @Controller 结合 @ResponseBody 使用不同,@RestController 注解的类中的所有方法隐式地具有 @ResponseBody 效果。这意味着所有的响应数据直接写入HTTP响应体中,通常是以JSON或XML格式返回,而不是解析为跳转路径。

3)简化开发:通过使用 @RestController,开发者可以更专注于业务逻辑的处理,而不必担心具体的数据呈现方式,Spring负责数据的序列化和HTTP消息的构建。

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello(){
        System.out.println("Hello World ~");
        return "Hello World ~";
    }
}

@ResponseBody

表示当前类下所有的方法返回值做为响应数据。方法的返回值如果是一个POJO对象或集合时,会先转换为JSON格式,在响应给浏览器。

一般来说,返回给前端需要按照统一格式的返回结果进行解析。定义在一个实体类Result来包含:

  • 响应状态码:当前请求是成功,还是失败

  • 状态码信息:给页面的提示信息

  • 返回的数据:给前端响应的数据(字符串、对象、集合)

    @Data+有参无参构造
    public class Result {
        private Integer code;//响应码,1 代表成功; 0 代表失败
        private String msg;  //响应码 描述字符串
        private Object data; //返回的数据
        //增删改 成功响应(不需要给前端返回数据)
        public static Result success(){
            return new Result(1,"success",null);
        }
        //查询 成功响应(把查询结果做为返回数据响应给前端)
        public static Result success(Object data){
            return new Result(1,"success",data);
        }
        //失败响应
        public static Result error(String msg){
            return new Result(0,msg,null);
        }
    }
    

@Component

声明bean的基础注解,可以实现类交给IOC容器管理

@Component //将当前对象交给IOC容器管理,成为IOC容器的bean
public class EmpDaoA implements EmpDao {
    @Override
    public List<Emp> listEmp() {
        //1. 加载并解析emp.xml
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
        System.out.println(file);
        List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
        return empList;
    }
}

@Controller

@Component的衍生注解,标注在控制器类上

@RestController  //@RestController = @Controller + @ResponseBody
public class EmpController {

    @Autowired //运行时,从IOC容器中获取该类型对象,赋值给该变量
    private EmpService empService ;

    @RequestMapping("/listEmp")
    public Result list(){
        //1. 调用service, 获取数据
        List<Emp> empList = empService.listEmp();

        //3. 响应数据
        return Result.success(empList);
    }
}

@Service

@Component的衍生注解,标注在业务类上

Service
public class EmpServiceA implements EmpService {

    @Autowired //运行时,从IOC容器中获取该类型对象,赋值给该变量
    private EmpDao empDao ;

    @Override
    public List<Emp> listEmp() {
        //1. 调用dao, 获取数据
        List<Emp> empList = empDao.listEmp();

        //2. 对数据进行转换处理 - gender, job
        empList.stream().forEach(emp -> {
            ...
        });
        return empList;
    }
}

@Repository

@Component的衍生注解,标注在数据访问类上(由于与mybatis整合@Mapper,用的少)

@Repository
public class EmpDaoA implements EmpDao {
    @Override
    public List<Emp> listEmp() {
        //1. 加载并解析emp.xml
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
        System.out.println(file);
        List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
        return empList;
    }
}

@Mapper

@Component的衍生注解,标注在数据访问类上(由于与mybatis整合@Mapper,用的少)

@Repository
public class EmpDaoA implements EmpDao {
    @Override
    public List<Emp> listEmp() {
        //1. 加载并解析emp.xml
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
        System.out.println(file);
        List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
        return empList;
    }
}

四、方法注解

@Bean

在配置类中,用于方法上,表示该方法返回一个Spring容器管理的Bean。

@Bean
public MyService myService() {
    return new MyServiceImpl();
}

@RequestMapping

  • 该注解在Spring MVC中用于映射Web请求到具体的处理方法或控制器类。
  • 它可以用于类级别和方法级别,帮助开发者定义URL路径和HTTP请求方法之间的对应关系。
  • 也可用于@Controller类上,用于统一配置协议的路径,在具体方法上拼接后缀。
@Controller
@RequestMapping("/api")
public class MyController {
    @RequestMapping("/hello")
    public String hello() {
        return "hello";
    }
}

上面的代码将“ /api/hello ”URL 映射到 hello 方法。
Spring MVC 提供了许多其他注解用于更精细地控制请求映射和处理,它们大多数是@RequestMapping的简化形式或扩展。


@GetMapping

用于处理HTTP GET请求,是@RequestMapping的快捷方式。

@GetMapping("/hello")
public String hello() {
    return "hello";
}

@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping

与上个注解一样,这些注解分别用于处理HTTP POST请求、HTTP PUT请求、HTTP DELETE请求、HTTP PATCH请求,是@RequestMapping的快捷方式。

@PostMapping("/submit")
public String submit(@RequestBody MyData data) {
    // 处理提交的数据
    return "result";
}

@PutMapping("/update")
public String update(@RequestBody MyData data) {
    // 处理更新的数据
    return "updated";
}

@DeleteMapping("/delete")
public String delete(@RequestParam int id) {
    // 处理删除请求
    return "deleted";
}

@PatchMapping("/patch")
public String patch(@RequestBody MyData data) {
    // 处理部分更新的数据
    return "patched";
}


五、参数注解

SpringMVC中,许多注解用于绑定请求体到方法参数。

@RequestParam

在Java Spring框架中,@RequestParam 是一个非常重要的注解,用于处理HTTP请求中的查询参数。这个注解将HTTP请求中的参数绑定到你的控制器方法的参数上。

作用:

1)参数映射@RequestParam 允许你从HTTP请求中提取查询参数(即URL中?后面的参数)或表单参数,并将其赋值给控制器方法的参数。例如,在处理一个GET请求中的查询参数或POST请求中的表单数据时非常有用。

2)数据类型转换:它自动将请求参数转换为指定的数据类型。例如,如果你的方法参数是一个整数,Spring会自动将请求参数从字符串转换为整数。

3)默认值设置:可以为请求参数指定默认值,如果请求中没有相应的参数,就会使用这个默认值。

4)可选与必需设置:可以指定某个请求参数是否必须。如果设置为必须(required=true),而请求中缺少该参数,Spring会抛出异常。

@RequestMapping(value = "/user", method = RequestMethod.GET)
public String getUser(@RequestParam(name = "id", required = true) Integer userId) {
    // 方法体可以使用userId,该参数来自于HTTP请求的查询参数id
    return "User ID: " + userId;
}

@PathVariable

用于处理来自URL路径的变量,而不是查询参数。例如,在RESTful URL结构中,@PathVariable 可以提取资源标识符。

@GetMapping("/users/{id}")
public String getUserById(@PathVariable("id") Integer userId) {
    return "User ID: " + userId;
}

@RequestBody

用于处理HTTP请求的主体内容,通常用于处理非表单数据的情况,如JSON或XML格式的输入。

@PostMapping("/users")
public String addUser(@RequestBody User user) {
    // 处理用户信息
    return "User added";
}

@RequestHeader

用于将请求的HTTP头映射到控制器方法的参数上。

@GetMapping("/greet")
public String greet(@RequestHeader("Accept-Language") String language) {
    return "Language: " + language;
}

@CookieValue

用于将HTTP请求中的Cookie数据映射到控制器方法的参数上。

@GetMapping("/track")
public String trackUser(@CookieValue("session_id") String sessionId) {
    return "Session: " + sessionId;
}

@DateTimeFormat

因为日期的格式多种多样(如:2022-12-12 10:05:45 、2022/12/12 10:05:45),那么对于日期类型的参数在进行封装的时候,需要通过@DateTimeFormat注解,以及其pattern属性来设置日期的格式。pattern属性中指定了哪种日期格式,前端的日期参数就必须按照指定的格式传递。

@RestController
public class RequestController {
    //日期时间参数
   @RequestMapping("/dateParam")
    public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime){
        System.out.println(updateTime);
        return "OK";
    }
}

六、变量注解

@Autowired

  • 依赖注入,是指IOC容器要为应用程序去提供运行时所依赖的资源,而资源指的就是对象。
  • 定义@Autowired这个注解,完成依赖注入的操作,而这个Autowired翻译过来叫:自动装配。
  • 默认是按照类型进行自动装配的(去IOC容器中找某个类型的对象,然后完成注入操作)
@Autowired
private MyService myService;


@Resource

  • 按照bean的名称进行注入。通过name属性指定要注入的bean的名称。

  • @Autowired 是spring框架提供的注解,而@Resource是JDK提供的注解。

  • @Autowired 默认是按照类型注入,而@Resource是按照名称注入。

@Resource(name = "myServiceImpl")
private MyService myService;


@Qualifier

  • 指定当前要注入的bean对象。 在@Qualifier的value属性中,指定注入的bean的名称。
  • @Qualifier注解不能单独使用,必须配合@Autowired使用
@Autowired
@Qualifier("myServiceImpl")
private MyService myService;


七、Bean作用域和生命周期

@Scope

  • 定义Bean的作用域
  • singleton:Spring IOC容器只会创建该bean定义的唯一实例。
  • prototype:每一次请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)都会产生一个新的bean实例。
@Scope("prototype")
@Component
public class MyPrototypeBean {
    // Bean逻辑
}

@PostConstruct

  • 方法在Bean初始化后调用。
@PostConstruct
public void init() {
    // 初始化逻辑
}

@PreDestroy

  • 方法在Bean销毁前调用。
@PreDestroy
public void destroy() {
    // 销毁逻辑
}

八、其他注解

有些注解增强了Spring框架的功能,使得事务管理、缓存处理和任务调度变得更为方便和强大。通过配置类中使用这些注解,可以轻松地启用和配置相应的功能。

事务启动注解@Transactional

该注解用于声明事务管理。它可以应用于类或方法级别,指示这些类或方法在一个数据库事务中执行。

功能

  1. 确保方法或类中的所有数据库操作在一个事务中执行。
  2. 如果发生任何异常,可以回滚整个事务。
  3. 支持设置事务的传播行为、隔离级别、超时时间和回滚规则。

相关注解

  1. @Transactional(readOnly = true): 指示事务为只读模式,优化数据库操作。
  2. @EnableTransactionManagement: 启用Spring的注解驱动的事务管理功能。
@Service
public class MyService {
    @Transactional
    public void performTransaction() {
        // 事务操作
    }
}

缓存启动注解@EnableCaching

该注解用于启用Spring的缓存抽象功能。它通常用于配置类中,以便Spring根据注解管理缓存。
功能

  1. 启用Spring缓存支持。
  2. 结合使用缓存注解(如 @Cacheable, @CachePut, @CacheEvict)管理缓存。

相关注解

  1. @Cacheable: 标记方法的返回值会被缓存。
  2. @CachePut: 更新缓存。
  3. @CacheEvict: 移除缓存。
  4. @CacheConfig: 配置缓存的共同设置。
@Configuration
@EnableCaching
public class CacheConfig {
    // 缓存配置
}

定时器启动注解@EnableScheduling

该注解用于启用Spring的计划任务调度功能。它通常用于配置类中,使得Spring能够发现和执行标记为计划任务的方法。
功能

  1. 启用Spring计划任务支持。Spring Task
  2. 配合 @Scheduled 注解,实现定时任务。
@Configuration
@EnableScheduling
public class SchedulingConfig {
    // 调度配置
}

相关注解

  1. @Scheduled: 标记一个方法为计划任务,并指定其执行的时间表(如 cron 表达式、固定延迟等)。
@Scheduled(cron = "0 0 * * * ?")
public void scheduledTask() {
    // 定时任务逻辑
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值