#第一种方式:通过Spring中的API接口实现。
##①首先编写接口文件和实现类
UserService接口:
package com.xkl.Service;
public interface UserService {
public void Add();
public void Delete();
public void Upgrade();
public void Query();
}
UserService接口实现类:
package com.xkl.Service;
public class UserServiceImpl implements UserService{
@Override
public void Add() {
System.out.println("增加用户");
}
@Override
public void Delete() {
System.out.println("删除用户");
}
@Override
public void Upgrade() {
System.out.println("更新用户");
}
@Override
public void Query() {
System.out.println("查询用户");
}
}
##②编写两个增强类。本例中用两个输出日志的类进行举例:有AfterLog和log可以放在同一个Log包下面
//log类:方法前
package com.xkl.Log;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class log implements MethodBeforeAdvice {
/*
* method:要执行的目标对象的方法。
* object:被调用的方法的参数
* o:目标对象
* */
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println(o.getClass().getName() + "的" + method.getName() + "方法被执行了");
}
}
AfterLog类:方法后
package com.xkl.Log;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class AfterLog implements AfterReturningAdvice{
/*
* returnvalue:返回值
* method:被调用的方法
* args:被调用的方法的对象的参数
* target:被调用的目标对象
* */
@Override
public void afterReturning(Object returnvalue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("执行了" + target.getClass().getName() + "的" + method.getName() + "方法,返回值为:" + returnvalue);
}
}
③接下来就是配置文件Spring容器(在Spring中注册,并实现aop切入实现):ApplicationContext.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.xkl.Service.UserServiceImpl"/>
<bean id="log" class="com.xkl.Log.log"/>
<bean id="afterLog" class="com.xkl.Log.AfterLog"/>
<!--aop的配置-->
<aop:config>
<!--切入点 expression:表达式匹配要执行的方法-->
<aop:pointcut id="pointcut" expression="execution(*
com.xkl.Service.UserServiceImpl.*(..))"/>
<!--执行环绕:advice-ref 执行方法 。 point-ref 切入点-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
</beans>
④最后进行测试
import com.xkl.Service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class aopTest {
@Test
public void testQuery(){
ApplicationContext Context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = Context.getBean("userService", UserService.class);
userService.Query();
}
}
##第二种方式:通过自定义来实现AOP[主要是切面定义]
①第一步:和第一种方法一样用相同的接口和接口实现类
这里就不累赘重述了。
②写一个我们自己的切入类。就是我们所要增强的项
package com.xkl.demo2.DiyAop;
/*
第一步:写我们自己的一个切入类。
* */
public class DiyPointcut {
public void before(){
System.out.println("------方法执行前------");
}
public void after(){
System.out.println("------方法执行后------");
}
}
③去Spring中注册
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<bean id="diy" class="com.xkl.demo2.DiyAop.DiyPointcut"/>
<bean id="userservice" class="com.xkl.demo2.UserService.UserserviceImpl"/>
<aop:config>
<!--第二种:使用aop的标签实现
自定义切面的注册。
-->
<aop:aspect ref="diy">
<aop:pointcut id="diyPointcut" expression="execution(*
com.xkl.demo2.UserService.UserserviceImpl.*(..))"/>//切入点的选择
<aop:before method="before" pointcut-ref="diyPointcut"/>
<aop:after method="after" pointcut-ref="diyPointcut"/>
</aop:aspect>
</aop:config>
</beans>
④最后进行测试
import com.xkl.demo2.UserService.Userservice;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AopSolutionTest {
@org.junit.Test
public void TestAop(){
ApplicationContext Context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
Userservice userservice = (Userservice) Context.getBean("userservice");
userservice.add();
}
}
#第三种方式:使用注解实现
①接口和实现类一样
②编写一个注解实现的增强类
package com.xkl.demo3;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class AnnotationPointcut {
@Before("execution(* com.xkl.demo2.UserService.UserserviceImpl.*(..))")
public void before(){
System.out.println("------方法执行前------");
}
@After("execution(* com.xkl.demo2.UserService.UserserviceImpl.*(..))")
public void after(){
System.out.println("------方法执行后------");
}
@Around("execution(* com.xkl.demo2.UserService.UserserviceImpl.*(..))")
public void around(ProceedingJoinPoint jp) throws Throwable{
System.out.println("环绕前");
System.out.println("方法是:"+jp.getSignature());
//执行目标方法proceed
Object proceed = jp.proceed();
System.out.println("环绕后");
System.out.println(proceed);
}
}
③在Spring中进行注册
很简单,直接就是引入一个切入面。动态创建代理
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<bean id="userservice" class="com.xkl.demo2.UserService.UserserviceImpl"/>
<bean id="annotationPointcut" class="com.xkl.demo3.AnnotationPointcut"/>
<aop:aspectj-autoproxy/>
</beans>
④测试
import com.xkl.demo2.UserService.Userservice;
import com.xkl.demo3.AnnotationPointcut;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AopSolution2Test {
@Test
public void Mytest(){
ApplicationContext Context = new ClassPathXmlApplicationContext("ApplicationContext2.xml");
Userservice userservice = Context.getBean("userservice", Userservice.class);
userservice.add();
}
}
三种方法比较:
第一种方式通过Spring的Api实现,功能更加强大,只需要定义增强类,就知道在哪执行了。
第二种通过自定义Aop切面类,在切面类内定义增强方法,之后在xml文件中进行注册,在切入点执行就行,任务更加明确。
第三种:通过使用注解的方式实现AOP,使得代码更加简洁。主要是xml的代码更加简洁。但是还是得用注解方式编写一个增强类的实现(需要标注这个类是切面类)。