标签:一个 调度 tno npoi not interface public OLE 改变
spring是方法级别的AOP框架,而我们主要也是以某个类的某个方法作为连接点,用动态代理的理论来说,就是要拦截某个方法织入对应AOP通知。
public interface RoleService { public void printRole(Role role); } @Component public class RoleServiceImpl implements RoleService { @Override public void printRole(Role role) { // TODO Auto-generated method stub System.out.println("{id="+role.getId()+",roleName="+role.getRoleName()+",note="+role.getNote()+"}"); } }
printRole方法作为AOP的连接点。用动态代理来说就是要为类RoleServiceImpl生成代理对象,然后拦截printRole方法,于是可以产生各种AOP通知方法。
选择好连接点就可以创建切面了,用动态代理来说,它就如同一个拦截器。在Spring中用@Aspect注解一个类,IOC容器就会认为这是一个切面了。
@Aspect public class RoleAspect { @Pointcut("execution(* test1.RoleServiceImpl.printRole(..))") public void print() { } @Before("print()") public void before() { System.out.println("before...."); } @After("print()") public void after() { System.out.println("after...."); } @AfterReturning("print()") public void afterReturning() { System.out.println("afterReturning...."); } @AfterThrowing("print()") public void afterThrowing() { System.out.println("afterThrowing...."); } }
@Pointcut定义一个切点。
4.测试AOP
//这个类是对Spring的Bean进行配置,采用的是注解方式 //表明这是个配置类,相当于xml文件 @Configuration //开启动态代理,开启AOP @EnableAspectJAutoProxy //扫描这个包下的所有bean @ComponentScan("test1") public class AopConfig { //表示创建一个bean,返回值类型表示bean的类型,方法名表示bean的id @Bean //生成一个切面实例 public RoleAspect getRoleAspect() { return new RoleAspect(); } }
//这个类是对Spring的Bean进行配置,采用的是注解方式 //表明这是个配置类,相当于xml文件 @Configuration //开启动态代理,开启AOP @EnableAspectJAutoProxy //扫描这个包下的所有bean @ComponentScan("test1") public class AopConfig { //表示创建一个bean,返回值类型表示bean的类型,方法名表示bean的id @Bean //生成一个切面实例 public RoleAspect getRoleAspect() { return new RoleAspect(); } }
before.... {id=1,roleName=role_name_1,note=note_1} after.... afterReturning.... ############ before.... after.... afterThrowing.... Exception in thread "main" java.lang.NullPointerException
显然切面的通知已经通过AOP织入约定的流程中了,这是可以使用AOP来处理一切需要切面的场景了。
是spring AOP中最强大的通知,它可以同时实现前置通知和后置通知,还保留了调度被代理对象原有方法的功能,强大而灵活,但如果不需要大量改变业务的逻辑,一般而言并不需要使用它。
@Around("print()") public void around(ProceedingJoinPoint jp) { System.out.println("around before...."); try { //反射连接点/切点方法 jp.proceed(); }catch(Throwable e) { e.printStackTrace(); } System.out.println("around after...."); }
上面的通知除了around()方法之外都是无参的,其实是可以传递参数来使用的。比如:
@Before("execution(* test1.RoleServiceImpl.printRole(..))"+"&&args(role)") public void before(Role role) { System.out.println("before...."); }
Spring AOP只是通过动态代理技术,把各类通知织入到它所约定的流程中,而事实上有时我们希望通过引入其他类的方法来得到更好的实现,这时就可以引入其他的方法了。
比如说引入一个方法检测printRole角色为空时不再打印:
public interface RoleVerifier { public boolean verify(Role role); } public class RoleVerifierImpl implements RoleVerifier { @Override public boolean verify(Role role) { return role!=null; } } 加入RoleVerifier到切面中: //value="test1.RoleServiceImpl+":表示对RoleServiceImpl类进行增强,也就是在RoleServiceImpl中引入一个新的接口 //defaultImpl=RoleVerifierImpl.class:代表其默认的实现类 @DeclareParents(value="test1.RoleServiceImpl+",defaultImpl=RoleVerifierImpl.class) public RoleVerifier roleVerifier;
ApplicationContext ctx=new AnnotationConfigApplicationContext(AopConfig.class); RoleService roleService=(RoleService)ctx.getBean(RoleService.class); RoleVerifier roleVerifier=(RoleVerifier)roleService; Role role=new Role(); role.setId(1); role.setRoleName("role_name_1"); role.setNote("note_1"); if(roleVerifier.verify(role)) { roleService.printRole(role); } System.out.println("############"); //测试异常通知 role=null; if(roleVerifier.verify(role)) { roleService.printRole(role); }else { System.out.println("空的"); }
标签:一个 调度 tno npoi not interface public OLE 改变
原文地址:https://www.cnblogs.com/xc-xinxue/p/12377289.html