1.使用aspect配置aop:
-
编写切面:
package com.aligns.spring.aop.aop.aspect;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;/**
- 定义切面:模拟事物
- @author kefan
*/
@Aspect
public class TransactionAspect {/** * 定义切入点 */ @Pointcut("execution(* com.aligns.spring.aop.service.*.*(..))") public void transactionPointCut(){ } /** * 定义前置通知:开启事物 */ @Before("transactionPointCut()") public void beginTransaction(){ System.out.println("事物开启...."); } /** * 定义后置通知:提交事物 */ @After("transactionPointCut()") public void CommitTransaction(){ System.out.println("事物提交...."); } /** * 定义异常通知:事物回滚 */ @AfterThrowing("transactionPointCut()") public void rollBackTransaction(){ System.out.println("事物回滚...."); }
}
-
在spring中配置
<?xml version="1.0" encoding="UTF-8"?><description>Spring Configuration</description> <!-- 使用Annotation自动注册Bean,解决事物失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。 --> <context:component-scan base-package="com.aligns.spring"><!-- base-package 如果多个,用“,”分隔 --> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan> <!--使用aspectj创建aop --> <aop:aspectj-autoproxy/> <bean id="logAspect" class="com.aligns.spring.aop.aop.aspect.TransactionAspect"></bean>
-
编写单元测试
package com.aligns.spring.aop.test;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;import com.aligns.spring.aop.service.AccountService;
import com.aligns.spring.aop.service.UserService;@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(“classpath*:spring-context.xml,classpath*:spring-context-jedis.xml”)
@ContextConfiguration(locations = { “classpath*:/spring-context-aspect-test.xml”})
@Transactional
public class AspectTest {@Resource AccountService accountService; @Resource UserService userService; @Test public void fun1(){ accountService.inAccount(); accountService.outAccount(); userService.addUser(); userService.deleteUser(); System.out.println(accountService); }
}
2.使用编程式配置aop
-
定义切面
package com.aligns.spring.aop.aop.programming;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;/**
- 定义切面:模拟事物
- @author kefan
*/
public class TransactionAspect {
/** * 定义切入点 */ @Pointcut("execution(* com.aligns.spring.aop.service.*.*(..))") public void transactionPointCut(){ } /** * 定义前置通知:开启事物 */ @Before("transactionPointCut()") public void beginTransaction(){ System.out.println("事物开启...."); } /** * 定义后置通知:提交事物 */ @After("transactionPointCut()") public void CommitTransaction(){ System.out.println("事物提交...."); } /** * 定义异常通知:事物回滚 */ @AfterThrowing("transactionPointCut()") public void rollBackTransaction(){ System.out.println("事物回滚...."); }
}
-
spring配置
<?xml version="1.0" encoding="UTF-8"?><description>Spring Configuration</description> <!-- 使用Annotation自动注册Bean,解决事物失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。 --> <context:component-scan base-package="com.aligns.spring"><!-- base-package 如果多个,用“,”分隔 --> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan> <!-- 定义切面 --> <bean id="logAspect" class="com.aligns.spring.aop.aop.aspect.TransactionAspect"></bean> <!-- aop相关的配置和说明 --> <aop:config> <!-- 定义相关的切面 --> <aop:aspect ref="logAspect"> <!-- 定义切入点 --> <aop:pointcut expression="execution(* com.aligns.spring.aop.service.*.*(..))" id="transactionPointCut"/> <aop:before pointcut-ref="transactionPointCut" method="beginTransaction"/> <aop:after pointcut-ref="transactionPointCut" method="CommitTransaction"/> <aop:after-throwing pointcut-ref="transactionPointCut" method="rollBackTransaction"/> </aop:aspect> </aop:config>
-
编写单元测试
package com.aligns.spring.aop.test;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;import com.aligns.spring.aop.service.AccountService;
import com.aligns.spring.aop.service.UserService;/**
- 测试变成式的创建aop应用
- @author kefan
/
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration("classpath:spring-context.xml,classpath*:spring-context-jedis.xml")
@ContextConfiguration(locations = { “classpath*:/spring-context-programming-test.xml”})
@Transactional
public class ProgrammingTest {@Resource AccountService accountService; @Resource UserService userService; @Test public void fun1(){ accountService.inAccount(); accountService.outAccount(); userService.addUser(); userService.deleteUser(); System.out.println(accountService); }
}
3.使用工厂模式配置aop
-
编写通知:(实现MethodBeforeAdvice等通知接口)
BeforeLoginAdviserpackage com.aligns.spring.aop.aop.proxyFactory;
import java.lang.reflect.Method;
import java.util.Arrays;import org.springframework.aop.MethodBeforeAdvice;
/**
- 用户登录前检查是否有证书的情况
- @author kefan
*/
public class BeforeLoginAdviser implements MethodBeforeAdvice {@Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("执行的目标对象为:"+target.getClass().getName()); System.out.println("执行的目标对象的方法为:"+method.getName()); System.out.println("执行的目标对象的方法为:"+Arrays.toString(args)); }
}
-
编写业务处理的接口
UserLoginpackage com.aligns.spring.aop.aop.proxyFactory;
public interface UserLogin {
public void login();
}
-
编写业务处理的实现类
UserLoginImpl
package com.aligns.spring.aop.aop.proxyFactory;
public class UserLoginImpl implements UserLogin {
@Override
public void login() {
System.out.println("用户登录....");
}
}
-
spring中配置代理工厂
<?xml version="1.0" encoding="UTF-8"?>
spring-context-factory-test.xml<description>Spring Configuration</description> <!-- 使用Annotation自动注册Bean,解决事物失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。 --> <context:component-scan base-package="com.aligns.spring"><!-- base-package 如果多个,用“,”分隔 --> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan> <!-- 编写通知:通常需要实现 --> <bean id="beforeAdviser" class="com.aligns.spring.aop.aop.proxyFactory.BeforeLoginAdviser"></bean> <!-- 目标方法的配置 --> <bean id="target" class="com.aligns.spring.aop.aop.proxyFactory.UserLoginImpl"></bean> <bean id="userLogin" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="target"/> <property name="singleton" value="false"></property> <property name="interceptorNames" value="beforeAdviser"></property> <property name="interfaces" value="com.aligns.spring.aop.aop.proxyFactory.UserLogin"></property> </bean>
-
编写单元测试
package com.aligns.spring.aop.test;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;import com.aligns.spring.aop.aop.proxyFactory.UserLogin;
/**
- 测试变成式的创建aop应用
- @author kefan
/
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration("classpath:spring-context.xml,classpath*:spring-context-jedis.xml")
@ContextConfiguration(locations = { “classpath*:/spring-context-factory-test.xml”})
@Transactional
public class FactoryTest {//@Resource AccountService accountService; //@Resource UserService userService; @Resource UserLogin userLogin; @Test public void fun1(){ userLogin.login(); }
}