Aop编程--注解与xml的实现

时间:2023-03-09 02:22:59
Aop编程--注解与xml的实现

一、注解方式

1、首先引入spring对于aop编程的jar支持包,spring框架没有的包请自行在网上下载。

aopalliance-alpha1.jar
aspectjrt.jar
aspectjweaver.jar
spring-aop-4.3.2.RELEASE.jar

2、在bean.xml中引入aop编程的名称空间。

http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd

3、在bean.xml中开启注解方式和开启注解扫描。

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<context:component-scan base-package="cn.itcast.e_aop_anno"></context:component-scan>

4、相关注解的解释

@Aspect指定一个类为切面类	(声明这是一个切面)
@Pointcut("execution(*包名.类名(可以用*代替包下的所有方法).*(..))") 指定切入点表达式
@Before("pointCut_()")前置通知: 目标方法之前执行
@After("pointCut_()")后置通知:目标方法之后执行(始终执行)
@AfterReturning("pointCut_()") 返回后通知: 执行方法结束前执行(异常不执行)
@AfterThrowing("pointCut_()") 异常通知: 出现异常时候执行
@Around("pointCut_()")环绕通知: 环绕目标方法执行

5、在注解模式下可以使用接口或不适用接口,为方便说明首先创建一个接口

public interface IUserDao {
void save();
}

6、实现接口的例子。

@Component   // 加入容器
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("-----核心业务:保存!!!------");
}
}

7、不实现接口的例子。

@Component   // 加入容器
@Scope("prototype")
public class OrderDao{
public void save() {
System.out.println("-----核心业务:保存!!!------");
}
}

8、切面类

@Component // 加入容器
@Aspect // 指定当前类为切面类
public class Aop {
// 指定切入点表单式: 拦截哪些方法; 即为哪些类生成代理对象
@Pointcut("execution(* 包名.*.*(..))")
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("环绕后....");
}
}

9、测试类。

public class App {
ApplicationContext ac = new ClassPathXmlApplicationContext("包名/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();
} @Deprecated
// 共性问题:如果目标对象有实现接口,在从容器中获取目标对象的时候,只能通过接口接收对象。
public void testApp2() {
// 错误代码: 只能用接口接收
UserDao userDao = (UserDao) ac.getBean("userDao");
System.out.println(userDao.getClass());
userDao.save();
} @Test
public void testGetObj() throws Exception {
OrderDao orderDao1 = (OrderDao) ac.getBean("orderDao");
OrderDao orderDao2 = (OrderDao) ac.getBean("orderDao");
System.out.println(orderDao1);
System.out.println(orderDao2); }
}

二、xml方式

1、首先引入spring对于aop编程的jar支持包,spring框架没有的包请自行在网上下载。

2、在bean.xml中引入aop编程的名称空间。

3、配置bean.xml。

     <!-- dao 实例 -->
<bean id="userDao" class="包名.UserDao"></bean>
<bean id="orderDao" class="包名.OrderDao"></bean> <!-- 切面类 -->
<bean id="aop" class="包名.Aop"></bean> <!-- Aop配置 -->
<aop:config>
<!-- 定义一个切入点表达式: 拦截哪些方法 -->
<aop:pointcut expression="execution(* 包名.*.*(..))" id="pt"/>
<!-- 切面 -->
<aop:aspect ref="aop">
<!-- 环绕通知 -->
<aop:around method="方法名" 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>

4、切面类。

// 切面类
public class Aop { public void begin(){
System.out.println("开始事务/异常");
} public void after(){
System.out.println("提交事务/关闭");
} public void afterReturning() {
System.out.println("afterReturning()");
} public void afterThrowing(){
System.out.println("afterThrowing()");
} public void around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕前....");
pjp.proceed(); // 执行目标方法
System.out.println("环绕后....");
} }

5、测试类。

public class App {
ApplicationContext ac = new ClassPathXmlApplicationContext("包名/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();
}
}