文章目录
05_Spring-Account的CRUD和AOP
Account表的CRUD实现
Dbutils使用:
主要是QueryRunner对象的使用,提供了query和update(新增、删除和修改)接口,BeanHandler、BeanListHandler和ScalarHandler帮我们封装结果集数据
思路分析
从Maven坐标(jar)的角度分析
- junit
- mysql驱动
- dbutils工具
- c3p0/dbcp数据库连接池
- spring-context(容器功能,帮我们管理对象以及注入对象)
从开发步骤的角度分析
- pom文件引入坐标
- pojo类
- dao层开发
- service层开发
- 使用Spring-context容器功能管理涉及到的所有对象及其依赖注入关系
xml中配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--数据库连接池-->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value=" root"/>
</bean>
<!--queryrunner对象-->
<bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
<constructor-arg name="ds" ref="dataSource"/>
</bean>
<!--dao层对象-->
<bean id="accountDao" class="com.ujiuye.spring.dao.AccountDaoImpl">
<property name="queryRunner" ref="queryRunner"/>
</bean>
<!--service层对象-->
<bean id="accountService" class="com.ujiuye.spring.service.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
</beans>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring?characterEncoding=utf8"/>
<property name="user" value="root"/>
<property name="password" value="luxingchi"/>
</bean>
注意:所有的数据库连接池使用套路都一样,都是使用其中一个核心类,然后赋值必要的数据库连接四要素
半xml半注解
注意:企业开发使用最多的方式
l xml配置文件依然存在,从配置文件启动容器
l 半xml:指的是第三方jar中的对象的定义配置在xml中
l 半注解:自己开发的类定义bean使用注解方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!--
配置注解扫描
base-package:配置所扫描包路径
-->
<context:component-scan base-package="com.ujiuye.spring"/>
<!--数据库连接池-->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!--queryrunner对象-->
<bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
<constructor-arg name="ds" ref="dataSource"/>
</bean>
</beans>
纯注解
注意:
纯注解方式(不需要引入额外的jar包)
**其实是对半xml****半注解模式的进一步改造
l **重点改造第三方jar****中对象的定义(注解实现)
l 容器初始化不是加载xml的方式了(纯注解不存在xml文件了)
/**
* @author liwenchuang
* @date 2019/4/8 16:46
* @description
*/
@Configuration // 标识当前类是Spring的一个配置类
@ComponentScan(value = {"com.ujiuye.spring"}) // 配置注解扫描
@PropertySource(value = {"db.properties"}) // 加载外部资源文件
@Import(value = {JdbcConfig.class}) // 加载其他配置文件
public class SpringConfig {
}
l @Configuration注解,表名当前类是一个配置类
@ComponentScan注解,替代context:component-scan
@ PropertySource,引入外部属性配置文件
@Import引入其他配置类
@Value对变量赋值,可以直接赋值,也可以使用${}读取资源配置文件中的信息
@Bean将方法返回对象加入SpringIOC容器
package com.ujiuye.spring.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
@Configuration // 标识当前类是Spring的一个配置类
@ComponentScan(value = {"com.ujiuye.spring"})
@PropertySource(value = {"db.properties"}) // @PropertySource注解用于加载属性配置文件
@Import(value = {JdbcConfig.class}) // @Import引入其他配置类
public class SpringConfig {
}
package com.ujiuye.spring.config;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class JdbcConfig {
// @Value注解对变量赋值:1、可以直接赋值 2、可以使用${}获取属性文件配置项
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
/**
* @Bean注解加载方法上
* 它可以把方法的返回值(返回值是一个对象),把这个对象加入到spring的ioc容器中
* @return
*/
@Bean("dataSource")
public DataSource createDataSource() {
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName(driver);
basicDataSource.setUrl(url);
basicDataSource.setUsername(username);
basicDataSource.setPassword(password);
return basicDataSource;
}
@Bean("queryRunner")
public QueryRunner createQueryRunner(@Qualifier("dataSource") DataSource dataSource) {
QueryRunner queryRunner = new QueryRunner(dataSource);
return queryRunner;
}
}
启动容器测试
@Test
public void testQueryAccountById() throws Exception {
// 启动ioc容器(全注解模式)
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
AccountService accountService = (AccountService) applicationContext.getBean("accountService");
Account account = accountService.queryAccountById(1);
System.out.println(account);
}
AOP
什么是AOP
AOP:Aspect Oriented Programming(面向切面编程/面向方面编程)
认识AOP,要从OOP说起
OOP(面向对象编程)
OOP三大特征:封装、继承和多态
OOP例子:
Horse类(马)、Dog类(狗)、Pig类(猪),它们都有eat()方法和run()方法,根据OOP编程思想,抽象出父类(提取一些公共的代码,避免代码重复)
大多数情况下,使用OOP就可以解决问题(代码重复问题),在某一些情况下使用OOP解决不了代码的一个重复问题
横切代码:
横切代码存在的问题
1、 横切代码往往是重复出现的
2、 横切代码和业务代码混杂在一起,代码会很臃肿,维护起来也比较麻烦
思考:将横切逻辑代码和业务逻辑代码分离
OOP纵向抽取已经解决不了横切代码的重复问题了,AOP独辟蹊径提出了“横向抽取”机制,将横切逻辑代码和业务逻辑代码分离
问题:抽取容易,抽取之后如何达到原有效果?拆着容易合起来难了
期望:**在不改变原有业务逻辑的情况下,悄无声息的把横切逻辑代码应用在业务逻辑代码上**,达到和原本一样的效果,这才是AOP真正发挥功力的地方
为什么叫AOP(面向切面编程)
AOP做的事情:在不改变原有业务逻辑的情况下,增强横切逻辑代码
“切”指的就是横切逻辑
原有的业务逻辑不能动,只能操作横切逻辑代码,所以我们叫做面向横切逻辑,
“面”:AOP对原有业务逻辑增强(横切逻辑),这件事往往影响的是很多个方法,有一个面的概念在里面
AOP的作用及优势
作用:在不改变原有业务逻辑的情况下,增强横切逻辑代码
优势:解决横切代码的重复问题,代码维护方便
Spring中AOP的实现方式
Spring的AOP的实现方式就是动态代理技术