springboot笔记

springboot笔记

1. 使用mybatis-plus

  1. 添加MyBatis Plus依赖项:在您的pom.xml文件中添加以下依赖项:

    <dependencies>
        <!-- MyBatis Plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>最新版本</version>
        </dependency>
        <!-- 其他依赖项... -->
    </dependencies>
    
  2. 配置数据库连接:在application.propertiesapplication.yml文件中添加数据库连接的配置信息,例如:

    spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase
    spring.datasource.username=root
    spring.datasource.password=your_password
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    
  3. 创建实体类:创建与数据库表对应的实体类。确保使用@TableName注解标记实体类对应的表名,以便MyBatis Plus能够正确地映射。

    import com.baomidou.mybatisplus.annotation.TableName;
    
    @TableName("user")
    public class User {
        private Long id;
        private String name;
        private Integer age;
        // 其他属性和方法...
    }
    
  4. 创建Mapper接口:创建与实体类对应的Mapper接口,并继承BaseMapper接口。MyBatis Plus将自动为您生成通用的CRUD方法。

    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    
    public interface UserMapper extends BaseMapper<User> {
        // 可以添加额外的自定义方法...
    }
    
  5. 配置Mapper扫描:在Spring Boot的配置类中,使用@MapperScan注解指定Mapper接口所在的包,以便自动扫描并注册Mapper Bean。

    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @MapperScan("com.example.mapper")
    public class MyBatisConfig {
        // 其他配置...
    }
    
  6. 使用Mapper接口:在您的服务类或控制器中,通过依赖注入的方式使用Mapper接口,并调用相应的方法进行数据库操作。

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserService {
        
        @Autowired
        private UserMapper userMapper;
        
        public User getUserById(Long id) {
            return userMapper.selectById(id);
        }
        
        // 其他方法...
    }
    
    
    
    

2. 使用redis

  1. 添加Redis依赖项:在您的pom.xml文件中添加以下依赖项:

    <dependencies>
        <!-- Redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- 其他依赖项... -->
    </dependencies>
    
  2. 配置Redis连接:在application.propertiesapplication.yml文件中添加Redis连接的配置信息,例如:

    spring.redis.host=localhost
    spring.redis.port=6379
    spring.redis.password=your_password
    
  3. 创建Redis配置类:在Spring Boot的配置类中,创建一个RedisConfig类,并添加@Configuration@EnableCaching注解,@EnableCaching注解用于启用Spring的缓存支持。

    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @EnableCaching
    public class RedisConfig {
        // 其他配置...
    }
    
  4. 使用Redis缓存:在您的服务类或控制器中,使用@Cacheable@CachePut等注解来标记需要缓存的方法,@Cacheable注解表示方法的结果将被缓存起来,@CachePut注解表示方法的结果将被更新到缓存中。

    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserService {
        
        @Cacheable(value = "users", key = "#id")
        public User getUserById(Long id) {
            // 从数据库或其他数据源获取用户信息
            return userRepository.findById(id);
        }
        
        @CachePut(value = "users", key = "#user.id")
        public User saveUser(User user) {
            // 保存用户信息到数据库或其他数据源
            return userRepository.save(user);
        }
    
        // 其他方法...
    }
    
  5. 使用RedisTemplate:如果需要更复杂的Redis操作,可以使用RedisTemplate进行操作,通过redisTemplate对象调用opsForValue()方法来执行Redis操作。

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserService {
        
        @Autowired
        private RedisTemplate<String, Object> redisTemplate;
        
        public void setValue(String key, Object value) {
            redisTemplate.opsForValue().set(key, value);
        }
        
        public Object getValue(String key) {
            return redisTemplate.opsForValue().get(key);
        }
        
        // 其他方法...
    }
    

3. 使用AOP

  1. 添加AOP依赖项:在您的pom.xml文件中添加以下依赖项:

    <dependencies>
        <!-- AOP -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!-- 其他依赖项... -->
    </dependencies>
    
  2. 创建一个切面类:创建一个类,使用@Aspect注解来标记它作为切面类。在切面类中,您可以定义各种通知(Before、After、Around等)和切入点表达式。

    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.stereotype.Component;
    
    @Aspect
    @Component
    public class LoggingAspect {
    
        @Before("execution(* com.example.demo.service.*.*(..))")
        public void beforeAdvice() {
            System.out.println("Before method execution");
        }
    }
    

    在上面的示例中,创建了一个切面类LoggingAspect,使用@Before注解来定义一个前置通知。execution(* com.example.demo.service.*.*(..))是切入点表达式,表示匹配com.example.demo.service包中的所有方法。

  3. 启用AOP:在Spring Boot的配置类上添加@EnableAspectJAutoProxy注解来启用AOP。

    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    
    @Configuration
    @EnableAspectJAutoProxy
    public class AppConfig {
        // 其他配置...
    }
    
  4. 切入点表达式

    execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
    

    其中,各个部分的含义如下:

    modifiers-pattern:表示方法的修饰符模式,如publicprivateprotected等,默认为*匹配任意修饰符。
    ret-type-pattern:表示方法的返回类型模式,如voidintjava.lang.String等,默认为*匹配任意返回类型。
    declaring-type-pattern:表示方法所在类的全限定名模式,如com.example.demo.service.*表示匹配com.example.demo.service包中的所有类,默认为*匹配任意类。
    name-pattern:表示方法名模式,如save*表示匹配以save开头的方法名,默认为*匹配任意方法名。
    param-pattern:表示方法参数模式,如(..)表示匹配任意参数列表,(java.lang.String)表示匹配只有一个String类型参数的方法。
    throws-pattern:表示方法抛出异常类型模式,如java.lang.Exception表示匹配抛出Exception异常的方法,默认为*匹配任意异常类型。
    

    下面是一些示例使用execution的切入点表达式:

    execution(public * com.example.demo.service.*.*(..)):
        匹配com.example.demo.service包中所有公共方法。
    execution(* com.example.demo.service.UserService.save*(..)):
        匹配com.example.demo.service.UserService类中以save开头的所有方法。
    execution(* com.example.demo.service.UserService.*(..)):
        匹配com.example.demo.service.UserService类中的所有方法。
    execution(* com.example.demo.service.UserService.*()):
        匹配com.example.demo.service.UserService类中不带任何参数的方法。
    execution(* com.example.demo.service.UserService.*(java.lang.String, ..)):
        匹配com.example.demo.service.UserService类中第一个参数为String类型的方法。
    execution(* com.example.demo.service.*.*(..) throws java.lang.Exception):
        匹配所有抛出Exception异常的方法。
    

4. 解决跨域问题

  1. 添加CORS依赖项:在您的pom.xml文件中添加以下依赖项:

    <dependencies>
        <!-- CORS -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 其他依赖项... -->
    </dependencies>
    
  2. 配置CORS:在Spring Boot的配置类中,添加WebMvcConfigurer的实现类,并重写addCorsMappings方法来配置CORS。

    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.CorsRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class CorsConfig implements WebMvcConfigurer {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("*")
                    .allowedMethods("GET", "POST", "PUT", "DELETE")
                    .allowedHeaders("*")
                    .allowCredentials(true)
                    .maxAge(3600);
        }
    }
    

    在上面的示例中,允许所有来源(allowedOrigins("*")),允许的HTTP方法(allowedMethods("GET", "POST", "PUT", "DELETE")),允许所有请求头(allowedHeaders("*")),启用跨域资源共享凭证(allowCredentials(true)),并设置预检请求的最大缓存时间(maxAge(3600))。

5. 域对象共享数据

  1. 使用HttpServletRequest对象:

    @Controller
    public class MyController {
        
        @RequestMapping("/storeData")
        public String storeData(HttpServletRequest request) {
            request.setAttribute("myData", "Hello, World!");
            return "redirect:/getData";
        }
        
        @RequestMapping("/getData")
        public String getData(HttpServletRequest request, Model model) {
            String data = (String) request.getAttribute("myData");
            model.addAttribute("data", data);
            return "myPage";
        }
    }
    
  2. 使用@SessionAttributes注解:

    @Controller
    @SessionAttributes("myData")
    public class MyController {
        
        @RequestMapping("/storeData")
        public String storeData(Model model) {
            model.addAttribute("myData", "Hello, World!");
            return "redirect:/getData";
        }
        
        @RequestMapping("/getData")
        public String getData(@ModelAttribute("myData") String data, Model model) {
            model.addAttribute("data", data);
            return "myPage";
        }
    }
    
  3. 使用HttpSession对象:

    @Controller
    public class MyController {
        
        @RequestMapping("/storeData")
        public String storeData(HttpSession session) {
            session.setAttribute("myData", "Hello, World!");
            return "redirect:/getData";
        }
        
        @RequestMapping("/getData")
        public String getData(HttpSession session, Model model) {
            String data = (String) session.getAttribute("myData");
            model.addAttribute("data", data);
            return "myPage";
        }
    }
    
  4. 使用@ModelAttribute注解:

    @Controller
    public class MyController {
        
        @ModelAttribute("myData")
        public String getMyData() {
            return "Hello, World!";
        }
        
        @RequestMapping("/getData")
        public String getData(@ModelAttribute("myData") String data, Model model) {
            model.addAttribute("data", data);
            return "myPage";
        }
    }
    
  5. 使用@SessionScoped注解:

    @Component
    @SessionScoped
    public class MySessionBean implements Serializable {
        
        private String myData;
        
        public String getMyData() {
            return myData;
        }
        
        public void setMyData(String myData) {
            this.myData = myData;
        }
    }
    
    @Controller
    public class MyController {
        
        @Autowired
        private MySessionBean sessionBean;
        
        @RequestMapping("/storeData")
        public String storeData() {
            sessionBean.setMyData("Hello, World!");
            return "redirect:/getData";
        }
        
        @RequestMapping("/getData")
        public String getData(Model model) {
            String data = sessionBean.getMyData();
            model.addAttribute("data", data);
            return "myPage";
        }
    }
    
  6. 使用数据库或缓存:

    @Controller
    public class MyController {
        
        @Autowired
        private MyDataRepository dataRepository;
        
        @RequestMapping("/storeData")
        public String storeData() {
            MyData myData = new MyData("Hello, World!");
            dataRepository.save(myData);
            return "redirect:/getData";
        }
        
        @RequestMapping("/getData")
        public String getData(Model model) {
            MyData myData = dataRepository.getMyData();
            model.addAttribute("data", myData.getData());
            return "myPage";
        }
    }
    
  7. 下表对比了上述6种Spring Boot中域对象共享数据的方式的优缺点及使用主义事项。

    方式优点缺点使用注意事项
    HttpServletRequest对象- 简单,直接使用Servlet API- 需要显式地在控制器方法中传递HttpServletRequest对象
    - 没有类型安全性
    - 需要注意数据存储和获取的位置,避免覆盖或错误访问数据
    - 需要处理异常情况,如请求未包含数据时的处理
    @SessionAttributes注解- 使用简单,通过注解指定要共享的模型属性
    - 数据存储在会话域中,可以在多个请求处理方法中共享
    - 只能在控制器类级别上共享数据,无法在不同控制器之间共享
    - 会话结束后,数据将被清除
    - 不适用于非Web环境的应用程序(如REST API)
    - 将需要共享的数据定义为模型属性,并使用@ModelAttribute访问和修改数据
    - 需要注意会话的生命周期,避免数据过早清除或过长保留
    HttpSession对象- 使用简单,直接使用HttpSession对象- 需要显式地在控制器方法中传递HttpSession对象
    - 没有类型安全性
    - 需要注意数据存储和获取的位置,避免覆盖或错误访问数据
    - 需要处理异常情况,如会话过期或不存在时的处理
    @ModelAttribute注解- 使用简单,通过注解定义模型属性,并自动存储和获取数据- 只能在同一控制器类中共享数据
    - 无法在不同的请求处理方法之间共享数据
    - 将需要共享的数据定义为模型属性,并使用@ModelAttribute访问和修改数据
    - 需要注意模型属性的作用域,避免数据过早清除或过长保留
    @SessionScoped注解- 数据存储在会话级别的Spring Bean中,可以在多个控制器和服务之间共享- 需要在会话bean中管理共享数据的状态
    - 需要手动创建和配置会话bean
    - 将共享的数据存储在会话bean中,并通过依赖注入在不同的控制器和服务中使用数据
    - 需要注意会话bean的生命周期,避免数据过早销毁
    使用数据库或缓存- 数据存储在持久化存储或缓存中,可以在不同的应用程序实例和会话之间共享- 需要引入数据库或缓存的依赖
    - 需要定义数据模型和访问方法
    - 需要处理并发访问和一致性问题
    - 将共享的数据存储在数据库或缓存中,并通过依赖注入在不同的控制器和服务中使用数据
    - 需要注意数据访问的性能和并发访问的安全性

6. 统一异常处理

  1. 创建一个自定义的 ResourceNotFoundException 异常类:

    public class ResourceNotFoundException extends RuntimeException {
    
        public ResourceNotFoundException(String message) {
            super(message);
        }
    
    }
    
  2. 在控制器中抛出该异常

    @RestController
    public class UserController {
    
        @GetMapping("/users/{id}")
        public User getUser(@PathVariable Long id) {
            User user = userRepository.findById(id);
            if (user == null) {
                throw new ResourceNotFoundException("User not found");
            }
            return user;
        }
    
    }
    
  3. 在全局异常处理器中处理 ResourceNotFoundException 异常:

    @ControllerAdvice
    public class GlobalExceptionHandler {
    
        @ExceptionHandler(ResourceNotFoundException.class)
        public ResponseEntity<String> handleResourceNotFoundException(ResourceNotFoundException ex) {
            String errorMessage = "资源不存在";
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorMessage);
        }
    
        @ExceptionHandler(Exception.class)
        public ResponseEntity<String> handleException(Exception ex) {
            String errorMessage = "发生了一个错误";
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
        }
    
    }
    

    在上面的代码中,在 GlobalExceptionHandler 类中添加了一个新的方法 handleResourceNotFoundException,用于处理 ResourceNotFoundException 异常。在该方法中,返回了一个自定义的错误信息,并设置了响应的状态码为 404(NOT_FOUND)。

    这样,当用户请求一个不存在的用户资源时,将会抛出 ResourceNotFoundException 异常,并由全局异常处理器捕获并处理,返回自定义的错误信息。

    注意事项:

    • 可以根据具体的业务需求,自定义不同类型的异常,并在全局异常处理器中处理。
    • 全局异常处理器可以处理多个不同类型的异常,可以根据实际需要添加多个异常处理方法。

7. 自定义过滤器

  1. 创建一个实现 javax.servlet.Filter 接口的自定义过滤器类。

    public class CustomFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            // 初始化方法
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            // 在这里编写对请求的处理逻辑
    
            // 继续调用过滤器链
            chain.doFilter(request, response);
        }
    
        @Override
        public void destroy() {
            // 销毁方法
        }
    }
    
  2. 创建一个配置类,并在该类中注册并配置过滤器。

    @Configuration
    public class FilterConfig {
    
        @Bean
        public FilterRegistrationBean<CustomFilter> customFilterRegistration() {
            FilterRegistrationBean<CustomFilter> registrationBean = new FilterRegistrationBean<>();
            registrationBean.setFilter(new CustomFilter());
            registrationBean.addUrlPatterns("/api/*"); // 指定过滤路径
            registrationBean.setOrder(1); // 设置过滤器的顺序
            return registrationBean;
        }
    }
    

    在上述示例中,使用 FilterRegistrationBean 注册了 CustomFilter 过滤器,并使用 addUrlPatterns 方法指定了过滤路径为 /api/*。还使用 setOrder 方法设置了过滤器的顺序为 1,这意味着它将在其他过滤器之前被执行。

  3. 在您的 Spring Boot 应用程序的入口类上添加 @ServletComponentScan 注解,以启用对 Filter 的扫描。

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

8. 自定义拦截器

  1. 创建实现 HandlerInterceptor 接口的自定义拦截器类。

    public class CustomInterceptor1 implements HandlerInterceptor {
        
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            // 在请求处理之前执行的逻辑
            return true; // 返回 true 表示继续执行后续的拦截器和请求处理方法
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                ModelAndView modelAndView) throws Exception {
            // 请求处理之后但未渲染视图时执行的逻辑
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                Exception ex) throws Exception {
            // 请求处理完成并且视图已渲染之后执行的逻辑
        }
    }
    
    public class CustomInterceptor2 implements HandlerInterceptor {
        // ... 自定义拦截器2的实现代码 ...
    }
    
  2. 创建一个配置类,实现 WebMvcConfigurer 接口,并重写 addInterceptors 方法进行拦截器的配置。

    @Configuration
    public class InterceptorConfig implements WebMvcConfigurer {
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new CustomInterceptor1()).addPathPatterns("/api/*"); // 指定拦截路径
            registry.addInterceptor(new CustomInterceptor2()).addPathPatterns("/admin/*"); // 指定拦截路径
        }
    }
    

    在上述示例中,分别创建了 CustomInterceptor1CustomInterceptor2 拦截器,并使用 addPathPatterns 方法分别指定了它们的拦截路径为 /api/*/admin/*

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值