Spring框架AOP思想
一、AOP简介
1、AOP概念:面向切面编程,通过预编译方式和运行期动态代理,实现程序功能的统一维护的一种技术;利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
2、AOP功能:Aop的功能主要是为了拦截或者实现日志安全检查,一些检查的工作,aop也常用于事务管理,防止垃圾数据进入数据库。
3、AOP中五种增强方式:
前置增强,表示在目标方法执行前实施增强
后置增强 , 表示在目标方法执行后实施增强
环绕增强,表示在目标方法执行前后实施增强
异常增强,表示在目标方法抛出异常后实施增强。
最终增强,表示在目标方法执行后不管有没有异常抛出总是实施增强
二、AOP的具体应用:
1、基于配置版
1.1、pom.xml依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--Aspectij这个jar包,不是spring框架的一部分,可以作为spring框架的一个组件,用来配合aop完成相应 的操作-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!--事务管理-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!--数据库连接-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
</dependencies>
1.2、核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--实例化目标类和增强类-->
<bean id="target" class="com.k9503.aop.xml.Target"></bean>
<bean id="handler" class="com.k9503.aop.xml.Handler"></bean>
<!–配置aop 1、切点 2、切面–>
<aop:config>
<aop:pointcut id="myPointCut" expression="execution(* com.k9503.aop.xml.Target.*(..))"></aop:pointcut>
<!--切面:增强类中的方法公共的代码:用户验证-->
<aop:aspect ref="handler">
<!--切面中的增强方法和作用的切点关联-->
<aop:before method="login" pointcut-ref="myPointCut"></aop:before>
<aop:after-returning method="afterReturn" pointcut-ref="myPointCut"></aop:after-returning>
<aop:around method="around" pointcut-ref="myPointCut"></aop:around>
<aop:after-throwing method="excep" pointcut-ref="myPointCut"></aop:after-throwing>
<aop:after method="end" pointcut-ref="myPointCut"></aop:after>
</aop:aspect>
<!--相当于监听器,一旦手动调用目标方法(切点),spring aop会自动调用增强方法-->
</aop:config>
</beans>
1.3、目标类
public class Target {
//目标方法1--切点
public void selectAccount(){
System.out.println("查询到账户余额:111111111.00");
}
//目标方法2--切点
public void getAccount(){
System.out.println("取款--取200000买车!");
}
}
1.4、增强类
//增强类 共用的功能
public class Handler {
//增强方法 验证用户
public void login(){
System.out.println("用户验证通过");
}
public void afterReturn(){
System.out.println("后置增强!");
}
public void around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕增强start。。。");
pjp.proceed();
System.out.println("环绕增强end。。。");
}
//在业务目标方法中出现类异常情况,则会执行异常增强,如果不存在异常,则不执行异常增强
public void excep(){
System.out.println("异常增强");
}
//不管有没有异常出现,均会执行的增强称之为最终增强
public void end(){
System.out.println("最终增强");
}
}
1.5、测试类
public class Test_1 {
@Test//手动调用目标方法,spring的aop会自动调用增强方法
public void test1(){
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
Target target = (Target) app.getBean("target");
target.selectAccount();//查询
target.getAccount();//取款
}
}
2、基于注解版
2.1、核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启类的注解 切点的注解-->
<context:component-scan base-package="com.k9503"></context:component-scan>
<!--开启切点注解-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
2.2、目标类
@Component("target")
public class Target {
//目标方法1--切点
public void selectAccount(){
System.out.println("查询到账户余额:111111111.00");
}
//目标方法2--切点
public void getAccount(){
System.out.println("取款--取200000买车!");
}
}
2.3、增强类
//增强类 共用的功能
@Component("handler")
@Aspect
public class Handler {
//增强方法 验证用户
@Before("execution(* com.k9503.aop.anno.Target.*(..))")
public void login(){
System.out.println("用户验证通过");
}
@AfterReturning("execution(* com.k9503.aop.anno.Target.*(..))")
public void afterReturn(){
System.out.println("后置增强!");
}
@Around("execution(* com.k9503.aop.anno.Target.*(..))")
public void around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕增强start。。。");
pjp.proceed();
System.out.println("环绕增强end。。。");
}
@AfterThrowing("execution(* com.k9503.aop.anno.Target.*(..))")
public void excep(){
System.out.println("异常增强");
}
@After("execution(* com.k9503.aop.anno.Target.*(..))")
public void end(){
System.out.println("最终增强");
}
}
2.4、测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/applicationContext.xml")
public class Test_2 {
@Autowired
@Qualifier("target")
private Target target;
@Test
public void test2(){
target.getAccount();
}
}
三、Spring事务管理
事务是一系列的动作,一旦其中有一个动作出现错误,必须全部回滚,系统将事务中对数据库的所有已完成的操作全部撤消,滚回到事务开始的状态,避免出现由于数据不一致而导致的接下来一系列的错误。事务的出现是为了确保数据的完整性和一致性,在目前企业级应用开发中,事务管理是必不可少的。
1、基于注解版的转账案例
1.1、核心配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启类的注解 切点的注解-->
<context:component-scan base-package="com.k9503"></context:component-scan>
<!--开启切点注解-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!--实例化jdbc模板对象 需要数据源-->
<bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--创建一个自己的dataSource-->
<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/k9503"/>
<property name="user" value="root"/>
<property name="password" value="171009"/>
</bean>
<!--配置事务管理 需要数据源-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--开启事务管理注解-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>
1.2、dao层
@Repository
public class AccountDao {
@Autowired
private JdbcTemplate template;//获取数据库连接对象
public void InMoney(String name,double money){
//转账
template.update("update account set money=money+? where name =?",money,name);
}
public void OutMoney(String name,double money){
//收款
template.update("update account set money=money-? where name =?",money,name);
}
}
1.3、service层
@Service
@Transactional//引入事务管理
public class AccountService {
@Autowired
private AccountDao dao;
public void exchangeAccount(String OutAccount,String InAccount,double money){
dao.InMoney(InAccount,money);//收款
dao.OutMoney(OutAccount,money);//转账
}
}
1.4、测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/applicationContext.xml")
public class Test_3 {
@Autowired
private AccountService service;
@Test
public void test(){
service.exchangeAccount("关羽","赵云",100);
}
}