使用AOP
- 什么是AOP
AOP是面向切面编程的缩写。在软件开发中,散布于应用中多处的功能被称为横切关注的(Cross-Cutting Concern)。
这些横切关注点从概念上是与应用程序的业务逻辑分离的(但是往往又要嵌入到应用的逻辑中),把这些横切关注点与业务逻辑分离开来就是AOP要解决的问题。
如果说依赖注入帮助我们解决了对象之间的耦合关系,那么AOP就是要把横切关注功能和它们所影响的对象之间进行解耦合。
- AOP的术语:
A.Advice(增强):定义切面的功能以及使用的时间。
- 前置增强(Before)
- 后置增强(After)
- 返回增强(AfterReturning)
- 异常增强(AfterThrowing)
- 环绕增强(Around)
B.Join Point(连接点):应用程序的逻辑跟切面交汇的一个点。
C.Pointcut(切入点):切入用来定义切面使用的位置。定义切面时可以使用利用切点表达式来描述在什么地方应用切面
AspectJ指示器 | 描述 |
---|---|
arg() | |
@args() | |
execution() | 连接到的执行方法 |
this() | |
target() | |
@target() | |
within() | |
@within() | |
@annotation |
D.Aspect(切面):增强和切入点的集合。
E.Introduction(引入):允许我们给现有的类添加新方法或属性。
F.Weaving(织入):把切面应用于目标对象(创建代理对象)的过程。
持久层使用JPA规范
1.在src目录下新建文件夹META-INF
2.新建xml文件:persistence.xml
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="Demo">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.kygo.entity.User</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost:3306/hib?useUnicode=true&characterEncoding=utf8" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="123456" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
3.新建JPAUtil工具类
public class JPAUtil {
private static ThreadLocal<EntityManager> threadLocal =
new ThreadLocal<>();
private static EntityManagerFactory factory = null;
static {
factory = Persistence.createEntityManagerFactory("Demo");
}
private JPAUtil() {
throw new AssertionError();
}
public static EntityManager getCurrentEM() {
EntityManager entityManager = threadLocal.get();
if (entityManager == null) {
entityManager = factory.createEntityManager();
threadLocal.set(entityManager);
}
return entityManager;
}
}
事务切面
@Aspect
public class TxAspect {
// 切面执行的位置
@Pointcut("execution(* com.kygo.biz.impl.*.*(..))")
public void foo() {}
// 切面执行的时机
@Around("foo()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
EntityTransaction tx = JPAUtil.getCurrentEM().getTransaction();
try {
tx.begin();
Object retValue = joinPoint.proceed(joinPoint.getArgs());
tx.commit();
return retValue;
} catch (Throwable e) {
tx.rollback();
throw e;
}
}
}
xml配置
<bean id="tx" class="com.kygo.aspect.TxAspect" />
<aop:config>
<aop:aspect id="txAspect" ref="tx">
<aop:around method="around"
pointcut="execution(* com.kygo.biz.impl.*.*(..))"/>
</aop:aspect>
</aop:config>