二、Spring纯注解开发

文章目录

一、配置类

在用@Autowired、@Resource、@Component及其衍生注解进行依赖注入之后,配置文件中就只配置了注解扫描器和命名空间,那么此时写这个配置文件,就显得有点多余

我们使用一个Java类作为配置类来代替这个配置文件

1、@Configuration注解配置类

用于设定当前类是配置类,代替了一堆命名空间和配置信息

2、@ComponentScan扫描包

代替了注解扫描器,扫描多个包的话参数传递数组格式
配置类


二、依赖注入

1、注入类

@Component衍生出@Controller、@Service、@Repository

2、给类对象注入属性

2.1 引用数据类型

  1. @Autowired:自动装配按类型
  2. @Qualifier与@Autowired配合:按类型,再按名称
  3. @Resource:精准,可按类型名称同时查

2.2 基本数据类型

@Value:可以看出来赋值int类型,即使带双引号也会自动判断
在这里插入图片描述


三、配置Bean

1、设置单例

@Repository
@Scope("singleton")  //设置单例
public class BookServiceImp implements BookService {
}

2、设置初始、销毁方法

@PostConstruct
public void init(){
    System.out.println("init...");
}
@PreDestroy
public void destory(){
    System.out.println("destory...");
}

四、注入第三方Bean

比如要使用druid,无法给人家源代码中去写注解标注接口/类
我们要使用独立的配置类来管理第三方Bean

1、注入步骤

  1. 定义一个方法返回要管理的对象
  2. 将返回值定义成这个Bean:@Bean
    第三方bean
  3. 将第三方Bean的配置导入到Spring配置类
@Configuration
@ComponentScan("com.jz")
@PropertySource("classpath:jdbc.properties")
@Import(JdbcConfig.class)
public class SpringConfig {
}

2、方法内要使用引用数据类型

直接在方法参数声明,方法内直接用就行

3、加载外部properties文件

上面的例子@Value中的值是写死的,想要从外部文件中加载

  1. 给spring的配置类上加注解@PropertySource("classpath:jdbc.properties")
  2. 在@Value中直接用占位符使用即可@Value("${jdbc.driverClassName}")
外部文件:
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/yunbook
jdbc.username=root
jdbc.password=123456

五、Aop

1、使用步骤

1.1 导入坐标

可以看到,导入spring-context之后,aop就包含在内了
spring-context依赖
除此之外,还需要导入aspectj的包

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.23</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
</dependency>

1.2 启动自动代理

给配置类加上@EnableAspectJAutoProxy,用于启用基于注解的自动代理功能

1.3 创建通知类,编写通知方法

  1. 注入容器:@Component
  2. 告知Spring容器,这个类是切面,让容器自动代理这个类:@Aspect

1.4 @Pointcut在通知类中定义切入点

切入点就是空方法体、无返回值的方法,在方法上通过@Pointcut注解指定切入点表达式,描述在哪个类/方法执行通知方法

1.5 描述切面,绑定通知与切入点之间的关系

在切入点之前还是之后执行通知,也就是切面。参数指定切入点方法名

切面

2、AOP工作流程

  1. spring容器启动
  2. 读取切面中绑定了通知的切入点
  3. 初始化bean,匹配切入点:匹配失败,直接创建这个类的对象;匹配成功,创建这个类的代理对象。代理对象可以拦截调用方法,进行操作
  4. 获取bean/代理bean,执行方法/代理对象增强方法

3、切入点表达式

@PointCut(execution(访问修饰符 返回值 包名.类名/接口名.方法名(参数) 异常))
访问修饰符和异常可以省略,描述切入点通常到接口而不是具体的类

3.1 切入点表达式使用通配符

*:匹配一个任意符号。

execution(public * com.jz.*.BookService.findBy*(*))
匹配public修饰的,返回值任意,findBy开头的,必须有一个参数的方法

..:匹配多个任意符号。

execution(public Book com..BookService.findById(..))
匹配public修饰的,返回值是Book类型的,com包下的任意包下的,BookService接口的,任意个参数的findById方法

+:匹配子类类型

execution(* *..*Service+.*(..))
匹配任意返回值类型的,任意包下的以Service结尾的类的子类的任意参数的方法

例题

匹配这个项目的所有方法:execution(* *..*(..))

4、通知类型

通知描述了抽取的共性内容,根据功能的不同,要加入到不同的位置

4.1 前置通知

@Before

4.2 后置通知

@After
前置后置通知

4.3 环绕通知(重点)

@Around
环绕通知要在通知内调用原方法操作,在调用原方法前后增强
既然原方法在通知内由代理调用,也要将方法的返回值返回出去,环绕通知的返回值Object
环绕通知
环绕通知呈现

4.4 返回后通知(了解)

@AfterReturning:方法成功运行完之后才执行通知。如果原方法内部发生异常,这个通知就不会执行;但是后置通知可以执行。

4.5 抛出异常后通知(了解)

@AfterThrowing:原方法内发生了异常才会执行通知

5、通知中获取原方法的数据

如果参数有JoinPoint或者ProeedJointPoint,那么一定是参数表的第一个参数

5.1 获取切入点方法参数:Object[ ] getArgs()

将这两个类对象传进通知的参数表,通知内用他们对象调用getArgs()方法,返回一个Object数组存储原方法参数。
JoinPoint:除了环绕通知都用这个
ProceedJointPoint:用于环绕通知

注意:环绕通知可以在通知内调用原方法,那么就可以获取这个参数检查其语法规范,不对的话对其修改再传进原方法执行。可以做自动类型转换这种操作。

5.2 获取切入点方法返回值

返回后通知和环绕通知可以获取

  1. 环绕通知:ProceedJoinPoint的对象调用proceed方法,执行原方法,返回值就是原方法的返回值
  2. 返回后通知:在返回后通知的参数表传参Object对象,并在它的注解指定returning为这个对象,就可以在通知内直接获取这个返回值对象。
@AfterReturning(value = "PointCut()", returning = "ret")
    public void methodAfterReturn(Object ret){
        System.out.println("原方法的返回值是:"+ ret);
        System.out.println("图书保存完毕");
}

5.3 获取切入点方法异常信息

抛出异常后通知和环绕通知

  1. 环绕通知:直接捕获
  2. 抛出异常后通知:
@AfterThrowing(value = "PointCut()", throwing = "throwable")
    public void methodAfterThrow(Throwable throwable){
        System.out.println("异常是"+throwable);
        System.out.println("抛出了异常,快去处理吧");
}


六、Spring事务

1、注入事务管理器

直接在jdbc配置类中注入事务管理器,并为事务管理器设置数据源

public class JdbcConfig {
    @Value("${jdbc.driverClassName}")
    private String driverClassName;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource){
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }
}

2、告诉spring容器使用注解形式做事务管理

@Configuration
@ComponentScan("com")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class, MyBatisConfig.class})
//启用注解形式做事务管理
@EnableTransactionManagement
public class SpringConfig {
}

3、给相应的业务上添加注解启用事务管理

可以加在类上也可以加在接口上
启用事务管理器


七、SpringMVC

1、简单使用

1.1 导入spring-webmvc,javax.servlet-api两个依赖

1.2 创建SpringMVC的配置类,扫描控制器所在包

1.3 创建servlet容器的配置类

用于初始化servlet容器,继承抽象类AbstractAnnotationConfigDispatcherServletInitializer,重写三个方法,分别为其加载springmvc的容器、spring容器、设置哪些请求归springmvc处理
代替了传统的web.xml

public class ServletContainerInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer{

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

1.4 创建控制器类(等同Servlet的功能)

2、请求

2.1 @RequestMapping设置请求路径

既是方法注解,也是类注解。
定义在类上面:设置当前类中所有请求处理方法的路径前缀
定义在方法上面:设置当前请求处理方法的具体路径
类注解的应用场景:在开发中,不可避免,可能与其他程序员设置的方法名一样,这样访问的时候就会冲突出错
方法名冲突
解决方法:在请求路径前加上自己负责模块的名字作为请求路径的前缀

2.1.1 请求路径前缀

设置请求路径前缀

2.1.2 post请求中文乱码

post请求中文乱码
解决:在servlet配置类中,设置过滤器

public class ServletContainerInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer{

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    //乱码处理,通过过滤器
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("utf-8");
        return new Filter[]{filter};
    }
}
2.1.3 强制请求方式

前端要想访问这个控制方法,就只能使用post请求
@RequestMapping(value = "/checkUser.do", method = RequestMethod.POST)

2.2 @RequestParam绑定请求参数

用于处理表单参数和get方式url后面的查询参数

  1. 设置接收的参数名,以及是否必须
    @RequestMapping("/del")
    public String del(@RequestParam(required = false, name = "userId") String id)
    对于这些方法参数:普通类型(基本数据类型)、pojo、复杂的pojo、数组
    如果请求参数名与方法参数名保持一致,不需要进行以上设计,就不需要写@RequestParam
  2. 绑定集合参数
    如果方法参数是集合,前面必须加@RequestParam绑定
    请求:http://localhost:8080/listParam?hobby=pingpang&hobby=swim
    接收:参数前加@RequestParam绑定
    @RequestMapping("/listParam")
    @ResponseBody
    public String listParam(@RequestParam List<String> hobby){}

2.3 @RequestBody获取请求体中JSON的数据

用于处理非表单数据,通常是json。
如果传递的是json数组,参数传递集合接收;传递的是json对象,参数用Java对象接收。

  1. 导入坐标:用于JSON和Java对象之间的转换
<dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
</dependency>
  1. @EnableWebMvc:给SpringMVC的配置类加上该注解,开启SpringMVC将json数据转为Java对象的功能
  2. 参数前加@RequestBody
    @RequestMapping("/jsonParam")
    @ResponseBody
    public String jsonParam(@RequestBody 参数){}

2.4 @DateTimeFormat指定参数日期格式

请求:
http://localhost:8080/Springmvc02_war_exploded/param/date?date=2024-07-15 18:25:27
接收:
@RequestMapping("/date")
@ResponseBody
public Date dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")Date date){}

3、响应:@ResponseBody

  1. @ResponseBody:将返回值序列化为json字符串设置到响应体中,不能转为json字符串就直接作为文本数据响应
  2. 既是类注解也是方法注解,类注解表示对所有方法有效
  3. 没有添加@ResponseBody,就会跳转与返回值同名的资源

3.1 返回值中文乱码问题

返回json格式字符串中文可能会乱码,在@RequestMapping注解中设置属性produces:
@RequestMapping(value = "/toJsonPOJO", produces = "application/json;charset=utf-8")
对象响应为json

4、REST风格

4.1 REST简介

url表现形式状态转换,支持更多的请求方式,比如put、delete

4.2 优点

传统风格:
http://localhost/user/del?id=1
http://localhost/user/save
rest风格:
http://localhost/users/1
http://localhost/users

  1. 隐藏资源的访问行为,无法通过地址得知在进行什么操作
  2. 简洁明了

4.3 REST行为动作

使用请求方式和路径区分对资源进行哪种操作,并且描述模块的行为名要用复数
http://localhost/users、http://localhost/users/1
get请求方式是查询:带参数id就是查指定的,不带参数就是查全部
delete请求删除指定用户
post请求添加用户信息
put请求修改用户信息

4.4 路径参数@PathVariable

怎么接收rest风格路径的请求参数?

  1. @RequestMapping中的参数用{ }括起来占位
  2. 方法参数前使用注解@PathVariable说明参数来自路径
    @RequestMapping(value = "/users/{id}", method = RequestMethod.GET)
    @ResponseBody
    public User selectOne(@PathVariable Integer id){}

4.5 简化rest

  1. @ResponseBody做类注解
  2. @Controller+@ResponseBody=@RestController
  3. @RequestMapping做类注解提出访问路径前缀
    两种方式对比
  4. 将@RequestMapping设置路径和请求方式合一
    请求方式与路径合一

5、三个接收请求参数的注解区别

@RequestParam:通常用于处理表单参数和查询参数
@RequestBody:通常用于处理非表单数据,接收解析转换json字符串
@PathVariable:用于接收路径参数,提取rest请求中的参数变量

6、表现层响应数据封装

如果后端接口的返回值不统一,那么前端不知道用什么来接收,也比较麻烦
所以在项目中一般都会封装一个返回值类,以确保所有接口都返回固定的格式。应该写在controller包下,因为是表现层的代码

6.1 结果集封装

响应的结果集

6.2 状态码封装

响应状态码

6.3 控制层使用

控制层使用

7、异常处理器

可以集中、统一地处理异常

7.1 异常分类

  1. 业务异常:用户是否规范操作
  2. 系统异常:项目工作中可预计且无法避免的异常
  3. 其他异常:未预期到的异常

7.2 异常如何处理

异常要分类处理,在表现层处理,用aop思想处理

7.2.1 自定义项目的系统异常和业务异常

都继承RuntimeExecption,不需要在方法后面throws声明,这两步就是为了做异常分类。
异常类内需要异常码,继续写在Code类中。
自定义两个异常

7.2.2 在可能触发异常的地方抛出自定义异常

模拟发生异常的地方包装

7.2.3 创建异常处理类集中处理异常

两个注解

  1. @RestControllerAdvice/@ControllerAdvice:类注解声明这个类是做异常处理的,前者用于rest请求的控制器
  2. @ExceptionHandler(自定义异常类的字节码文件):方法注解,用于声明这个方法处理那种类型的异常,括号内传异常类的字节码文件。
    异常处理器

八、SSM整合

Spring、SpringMVC、MyBatis整合在一起工作

1、提前准备工作

  1. 五个配置类:springconfig、springmvcconfig、servletconfig、jdbcconfig(事务)、mybatisconfig
  2. 注意pom文件内的jar版本要对应,直接用提供的
  3. 一个数据源配置文件:jdbc.properties
  4. 注意修改几个配置文件内的扫描包路径
  5. 为业务层开启事务
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值