Aop--面向切面编程
- 采用横向抽取的方式,在运行阶段将增强代码织入目标对象的思想--底层采用动态代理
- aop应用场景
- 事务管理,日志系统,性能监测,缓存等..
- aop的框架
- 1.spring aop(spring-aop.jar)
- 2.aspectj(aspects.jar)
- 3.Jboss
- 我们经常用前俩个
- aop专业术语:
- target:目标对象 代理里叫委托类对象
- advice:通知,增强代码(遵循特定规范的增强代码叫做通知)
- joinpoint:连接点,目标对象方法
- pointcut:切入点.真正添加增强的目标对象的方法--切入点一般都是连接点,反之不一定
- weaver:织入.增强代码添加到切入点的过程
- aspect:切面,增强代码和切入点连接形成的逻辑面
- aop编程:
- 1.导入jar包
- 4+1
- spring-aop.jar spring的aop框架
- aspects.jar aspectj规范
- aopalliance-1.0.jar aop联盟(规范通知)
- aspectjweaver-1.8.5.jar 实现织入的
- 如果要使用spring整合Junit来测试的话,我们还要导入spring-test-4.1.6.RELEASE.jar
- 2.目标类对象UserServiceImpl.java
- src下创建service包,里面创建UserService接口
- 1.导入jar包
package service;
public interface UserService {
void addUser();
void deleteUser();
}
service包下创建impl子包,里面创建UserService的实现类UserServiceImpl
package service.impl;
import service.UserService;
public class UserServiceImpl implements UserService {
/*
* 这里正常应该是调用dao的方法,这里我们就用输出语句代替了
*/
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
}
-
3.增强代码 MyAspect.java
-
src下创建aspect包,在里面创建MyAspect这个增强代码类
-
package aspect;
public class MyAspect {
public void before(){
System.out.println("开启事务");
}
public void after(){
System.out.println("提交事务");
}
}
-
4.需要创建目标类对象,创建切面类对象,然后织入就可以了.这些都需要在我们的spring容器中配置,下面写一下配置文件
<?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: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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
<!-- 1.创建目标类对象 -->
<bean id="userservice" class="service.impl.UserServiceImpl"></bean>
<!-- 2.创建增强代码类对象 -->
<bean id="myaspect" class="aspect.MyAspect"></bean>
<!-- 3.织入增强代码
织入需要我们使用aop容器.所以这里要导入aop的命名空间来对它进行配置
aop:config中有一个expose-proxy="false"属性,默认是false,指代默认使用jdk代理,咱们这里一般不写
-->
<aop:config >
<!--
aop:pointcut 配置切入点 :往哪个地方织入增强代码
属性expression:指明哪些才是切入点
execution(返回值 包名.类名.方法名(参数列表))
如果不管返回值的话可以用 *:通配符
下面的写法是service包下所有的类的所有方法
-->
<aop:pointcut expression="execution(* service..*(..))" id="myPointcut"/>
<!--
配置切面:这里可以理解为就是找到切入点之后,告诉它怎么去添加
ref:使用哪一个增强,值就是增强代码类的id
-->
<aop:aspect ref="myaspect">
<!--
前置增强 :切入点的方法执行之前需要执行的增强代码
method:增强代码类里面的方法名称
pointcut-ref:前面配置的切入点
整体来说就是 将myaspect这个增强代码类的before方法添加到切入点(service包下所有的类的所有方法)里的前面去
-->
<aop:before method="before" pointcut-ref="myPointcut"/>
<!-- 后置增强 -->
<aop:after-returning method="after" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config>
</beans>
接下来我们去写个测试类,测试一下
package test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import service.UserService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class Test {
@Autowired
UserService service;
@org.junit.Test
public void test(){
service.addUser();
service.deleteUser();
}
}
结果如下:
好了,上面的过程就是我们aop的编程.不过我们这里使用的是xml的方式. 后面我们再说注解实现