Spring的Aop编程

来源:互联网 发布:二次规划最优化 编辑:程序博客网 时间:2024/06/06 09:19

 AOP编程

1 概述:

Aop  aspect object programming  面向切面编程

功能: 让关注点代码与业务代码分离!

关注点,

重复代码就叫做关注点;

切面,

 关注点形成的类,就叫切面()

 面向切面编程,就是指 对很多功能都有的重复的代码抽取,再在运行的时候网业务方法上动态植入“切面类代码”。

切入点,

执行目标对象方法,动态植入切面代码。

可以通过切入点表达式,指定拦截哪些类的哪些方法; 给指定的类在运行的时候植入切面类代码。

 

2 注解方式实现AOP编程

步骤:

1) 先引入aop相关jar文件

2bean.xml中引入aop名称空间

3) 开启aop注解

4) 使用注解

@Aspect 指定一个类为切面类

@Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))")  指定切入点表达式

 

@Before("pointCut_()") 前置通知: 目标方法之前执行

@After("pointCut_()") 后置通知:目标方法之后执行(始终执行)

@AfterReturning("pointCut_()")     返回后通知: 执行方法结束执行(异常不执行)

@AfterThrowing("pointCut_()") 异常通知:  出现异常时候执行

@Around("pointCut_()") 环绕通知: 环绕目标方法执行

 

1. IUserDao.java

// 接口

public interface IUserDao {

void save();

}

 

2. UserDao.java

/**

 * 目标对象

 * @author Jie.Yuan

 *

 */

@Component   //加入容器

public class UserDaoimplements IUserDao{

 

@Override

public void save() {

System.out.println("-----核心业务:保存!!!------");

}

}

 

3. Aop.java  切面类

 

@Component

@Aspect  //指定当前类为切面类

public class Aop {

 

// 指定切入点表单式: 拦截哪些方法; 即为哪些类生成代理对象

@Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))")

public void pointCut_(){

}

// 前置通知 : 在执行目标方法之前执行

@Before("pointCut_()")

public void begin(){

System.out.println("开始事务/异常");

}

// 后置/最终通知:在执行目标方法之后执行  【无论是否出现异常最终都会执行】

@After("pointCut_()")

public void after(){

System.out.println("提交事务/关闭");

}

// 返回后通知: 在调用目标方法结束后执行 【出现异常不执行】

@AfterReturning("pointCut_()")

public void afterReturning() {

System.out.println("afterReturning()");

}

// 异常通知: 当目标方法执行异常时候执行此关注点代码

@AfterThrowing("pointCut_()")

public void afterThrowing(){

System.out.println("afterThrowing()");

}

// 环绕通知:环绕目标方式执行

@Around("pointCut_()")

public void around(ProceedingJoinPoint pjp)throws Throwable{

System.out.println("环绕前....");

pjp.proceed();  // 执行目标方法

System.out.println("环绕后....");

}

}

4. bean.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"

    xmlns:p="http://www.springframework.org/schema/p"

    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="cn.itcast.e_aop_anno"></context:component-scan>

<!-- 开启aop注解方式-->

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>   

 

 

App.java

 

public class App {

ApplicationContext ac =

new ClassPathXmlApplicationContext("cn/itcast/e_aop_anno/bean.xml");

 

// 目标对象有实现接口,spring会自动选择“JDK代理

@Test

public void testApp() {

IUserDao userDao = (IUserDao) ac.getBean("userDao");

System.out.println(userDao.getClass());

userDao.save();

}

// 目标对象没有实现接口,spring会用cglib代理

@Test

public void testCglib() {

OrderDao orderDao = (OrderDao) ac.getBean("orderDao");

System.out.println(orderDao.getClass());

orderDao.save();

}

}

 

 

3 XML方式实现AOP编程

 

Xml实现aop编程:

1) 引入jar文件  

2) 引入aop名称空间

3aop 配置

* 配置切面类 (重复执行代码形成的类)

* aop配置

拦截哪些方法 / 拦截到方法后应用通知代码

 

 

<?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:p="http://www.springframework.org/schema/p"

    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">

<!-- dao 实例-->

<bean id="userDao" class="cn.itcast.f_aop_xml.UserDao"></bean>

<bean id="orderDao" class="cn.itcast.f_aop_xml.OrderDao"></bean>

<!-- 切面类 -->

<bean id="aop" class="cn.itcast.f_aop_xml.Aop"></bean>

<!-- Aop配置-->

<aop:config>

<!-- 定义一个切入点表达式: 拦截哪些方法-->

<aop:pointcut expression="execution(* cn.itcast.f_aop_xml.*.*(..))" id="pt"/>

<!-- 切面 -->

<aop:aspect ref="aop">

<!-- 环绕通知 -->

<aop:around method="around" pointcut-ref="pt"/>

<!-- 前置通知: 在目标方法调用前执行-->

<aop:before method="begin" pointcut-ref="pt"/>

<!-- 后置通知: -->

<aop:after method="after"pointcut-ref="pt"/>

<!-- 返回后通知 -->

<aop:after-returning method="afterReturning"pointcut-ref="pt"/>

<!-- 异常通知 -->

<aop:after-throwing method="afterThrowing" pointcut-ref="pt"/>

</aop:aspect>

</aop:config>

</beans>  

 

4  切入点表达式

切入点表达式,

可以对指定的“方法”进行拦截;  从而给指定的方法所在的类生层代理对象。

 

 

<?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:p="http://www.springframework.org/schema/p"

    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">

<!-- dao 实例-->

<bean id="userDao" class="cn.itcast.g_pointcut.UserDao"></bean>

<bean id="orderDao" class="cn.itcast.g_pointcut.OrderDao"></bean>

<!-- 切面类 -->

<bean id="aop" class="cn.itcast.g_pointcut.Aop"></bean>

<!-- Aop配置-->

<aop:config>

<!-- 定义一个切入点表达式: 拦截哪些方法-->

<!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.*.*(..))" id="pt"/>-->

<!-- 【拦截所有public方法】-->

<!--<aop:pointcut expression="execution(public * *(..))" id="pt"/>-->

<!-- 【拦截所有save开头的方法 】-->

<!--<aop:pointcut expression="execution(* save*(..))" id="pt"/>-->

<!-- 【拦截指定类的指定方法,拦截时候一定要定位到方法】-->

<!--<aop:pointcut expression="execution(public * cn.itcast.g_pointcut.OrderDao.save(..))" id="pt"/>-->

<!-- 【拦截指定类的所有方法】-->

<!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.*(..))" id="pt"/>-->

<!-- 【拦截指定包,以及其自包下所有类的所有方法】-->

<!--<aop:pointcut expression="execution(* cn..*.*(..))" id="pt"/>-->

<!-- 【多个表达式】 -->

<!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) || execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->

<!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) or execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->

<!-- 下面2个且关系的,没有意义-->

<!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) && execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->

<!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) and execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->

<!-- 【取非值】 -->

<!--<aop:pointcut expression="!execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->

<aop:pointcut expression=" not execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>

<!-- 切面 -->

<aop:aspect ref="aop">

<!-- 环绕通知 -->

<aop:around method="around" pointcut-ref="pt"/>

</aop:aspect>

</aop:config>

</beans>    

1 0
原创粉丝点击