/** * Create a ComposablePointcut based on the given Pointcut. * @param pointcut the original Pointcut */ public ComposablePointcut(Pointcut pointcut) { Assert.notNull(pointcut, "Pointcut must not be null"); this.classFilter = pointcut.getClassFilter(); this.methodMatcher = pointcut.getMethodMatcher(); }
/** * Apply an intersection with the given Pointcut. * @param other the Pointcut to apply an intersection with * @return this composable pointcut (for call chaining) */ public ComposablePointcut intersection(Pointcut other) { this.classFilter = ClassFilters.intersection(this.classFilter, other.getClassFilter()); this.methodMatcher = MethodMatchers.intersection(this.methodMatcher, other.getMethodMatcher()); return this; }
@Override public boolean matches(Method method, Class<?> targetClass) { // We're either instantiated and matching on declared pointcut, // or uninstantiated matching on either pointcut... return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass)) || this.preInstantiationPointcut.getMethodMatcher().matches(method, targetClass); }
/** * Apply a union with the given Pointcut. * <p>Note that for a Pointcut union, methods will only match if their * original ClassFilter (from the originating Pointcut) matches as well. * MethodMatchers and ClassFilters from different Pointcuts will never * get interleaved with each other. * @param other the Pointcut to apply a union with * @return this composable pointcut (for call chaining) */ public ComposablePointcut union(Pointcut other) { this.methodMatcher = MethodMatchers.union( this.methodMatcher, this.classFilter, other.getMethodMatcher(), other.getClassFilter()); this.classFilter = ClassFilters.union(this.classFilter, other.getClassFilter()); return this; }
MethodMatcher methodMatcher = pc.getMethodMatcher(); if (methodMatcher == MethodMatcher.TRUE) {
/** * Build a 'safe' pointcut that excludes the AspectJ advice method itself. * @return a composable pointcut that builds on the original AspectJ expression pointcut * @see #getPointcut() */ public final Pointcut buildSafePointcut() { Pointcut pc = getPointcut(); MethodMatcher safeMethodMatcher = MethodMatchers.intersection( new AdviceExcludingMethodMatcher(this.aspectJAdviceMethod), pc.getMethodMatcher()); return new ComposablePointcut(pc.getClassFilter(), safeMethodMatcher); }
/** * Perform the least expensive check for a pointcut match. * @param pointcut the pointcut to match * @param method the candidate method * @param targetClass the target class * @param args arguments to the method * @return whether there's a runtime match */ public static boolean matches(Pointcut pointcut, Method method, Class<?> targetClass, Object... args) { Assert.notNull(pointcut, "Pointcut must not be null"); if (pointcut == Pointcut.TRUE) { return true; } if (pointcut.getClassFilter().matches(targetClass)) { // Only check if it gets past first hurdle. MethodMatcher mm = pointcut.getMethodMatcher(); if (mm.matches(method, targetClass)) { // We may need additional runtime (argument) check. return (!mm.isRuntime() || mm.matches(method, targetClass, args)); } } return false; }
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); boolean match; if (mm instanceof IntroductionAwareMethodMatcher) {
@Test public void testAdvisorReturnsFalseWhenMethodInvocationNotDefined() throws Exception { Class<TargetObject> clazz = TargetObject.class; Method method = clazz.getMethod("makeLowerCase", new Class[] { String.class }); MethodSecurityMetadataSource mds = mock(MethodSecurityMetadataSource.class); when(mds.getAttributes(method, clazz)).thenReturn(null); MethodSecurityMetadataSourceAdvisor advisor = new MethodSecurityMetadataSourceAdvisor( "", mds, ""); assertThat(advisor.getPointcut().getMethodMatcher().matches(method, clazz)).isFalse(); }
@Test public void testAdvisorReturnsTrueWhenMethodInvocationIsDefined() throws Exception { Class<TargetObject> clazz = TargetObject.class; Method method = clazz.getMethod("countLength", new Class[] { String.class }); MethodSecurityMetadataSource mds = mock(MethodSecurityMetadataSource.class); when(mds.getAttributes(method, clazz)).thenReturn( SecurityConfig.createList("ROLE_A")); MethodSecurityMetadataSourceAdvisor advisor = new MethodSecurityMetadataSourceAdvisor( "", mds, ""); assertThat( advisor.getPointcut().getMethodMatcher().matches(method, clazz)).isTrue(); } }
@Test public void testMatchAll() throws NoSuchMethodException { Pointcut pc = new ComposablePointcut(); assertTrue(pc.getClassFilter().matches(Object.class)); assertTrue(pc.getMethodMatcher().matches(Object.class.getMethod("hashCode"), Exception.class)); }
@Test public void testMatchWithArgs() throws Exception { String expression = "execution(void org.springframework.tests.sample.beans.TestBean.setSomeNumber(Number)) && args(Double)"; Pointcut pointcut = getPointcut(expression); ClassFilter classFilter = pointcut.getClassFilter(); MethodMatcher methodMatcher = pointcut.getMethodMatcher(); assertMatchesTestBeanClass(classFilter); // not currently testable in a reliable fashion //assertDoesNotMatchStringClass(classFilter); assertTrue("Should match with setSomeNumber with Double input", methodMatcher.matches(setSomeNumber, TestBean.class, new Double(12))); assertFalse("Should not match setSomeNumber with Integer input", methodMatcher.matches(setSomeNumber, TestBean.class, new Integer(11))); assertFalse("Should not match getAge", methodMatcher.matches(getAge, TestBean.class)); assertTrue("Should be a runtime match", methodMatcher.isRuntime()); }
@Test public void testMatchExplicit() { String expression = "execution(int org.springframework.tests.sample.beans.TestBean.getAge())"; Pointcut pointcut = getPointcut(expression); ClassFilter classFilter = pointcut.getClassFilter(); MethodMatcher methodMatcher = pointcut.getMethodMatcher(); assertMatchesTestBeanClass(classFilter); // not currently testable in a reliable fashion //assertDoesNotMatchStringClass(classFilter); assertFalse("Should not be a runtime match", methodMatcher.isRuntime()); assertMatchesGetAge(methodMatcher); assertFalse("Expression should match setAge() method", methodMatcher.matches(setAge, TestBean.class)); }
@Test public void testMatchWithTypePattern() throws Exception { String expression = "execution(* *..TestBean.*Age(..))"; Pointcut pointcut = getPointcut(expression); ClassFilter classFilter = pointcut.getClassFilter(); MethodMatcher methodMatcher = pointcut.getMethodMatcher(); assertMatchesTestBeanClass(classFilter); // not currently testable in a reliable fashion //assertDoesNotMatchStringClass(classFilter); assertFalse("Should not be a runtime match", methodMatcher.isRuntime()); assertMatchesGetAge(methodMatcher); assertTrue("Expression should match setAge(int) method", methodMatcher.matches(setAge, TestBean.class)); }
@Test public void testPerTarget() throws SecurityException, NoSuchMethodException { AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(); ajexp.setExpression(AspectJExpressionPointcutTests.MATCH_ALL_METHODS); InstantiationModelAwarePointcutAdvisorImpl ajpa = new InstantiationModelAwarePointcutAdvisorImpl( ajexp, TestBean.class.getMethod("getAge"), af, new SingletonMetadataAwareAspectInstanceFactory(new PerTargetAspect(), "someBean"), 1, "someBean"); assertNotSame(Pointcut.TRUE, ajpa.getAspectMetadata().getPerClausePointcut()); assertTrue(ajpa.getAspectMetadata().getPerClausePointcut() instanceof AspectJExpressionPointcut); assertTrue(ajpa.isPerInstance()); assertTrue(ajpa.getAspectMetadata().getPerClausePointcut().getClassFilter().matches(TestBean.class)); assertFalse(ajpa.getAspectMetadata().getPerClausePointcut().getMethodMatcher().matches( TestBean.class.getMethod("getAge"), TestBean.class)); assertTrue(ajpa.getAspectMetadata().getPerClausePointcut().getMethodMatcher().matches( TestBean.class.getMethod("getSpouse"), TestBean.class)); }
@Test public void testPerTargetAspect() throws SecurityException, NoSuchMethodException { TestBean target = new TestBean(); int realAge = 65; target.setAge(realAge); TestBean itb = (TestBean) createProxy(target, getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new PerTargetAspect(), "someBean")), TestBean.class); assertEquals("Around advice must NOT apply", realAge, itb.getAge()); Advised advised = (Advised) itb; ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor sia = (ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor) advised.getAdvisors()[1]; assertTrue(sia.getPointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null)); InstantiationModelAwarePointcutAdvisorImpl imapa = (InstantiationModelAwarePointcutAdvisorImpl) advised.getAdvisors()[3]; LazySingletonAspectInstanceFactoryDecorator maaif = (LazySingletonAspectInstanceFactoryDecorator) imapa.getAspectInstanceFactory(); assertFalse(maaif.isMaterialized()); // Check that the perclause pointcut is valid assertTrue(maaif.getAspectMetadata().getPerClausePointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null)); assertNotSame(imapa.getDeclaredPointcut(), imapa.getPointcut()); // Hit the method in the per clause to instantiate the aspect itb.getSpouse(); assertTrue(maaif.isMaterialized()); assertEquals("Around advice must apply", 0, itb.getAge()); assertEquals("Around advice must apply", 1, itb.getAge()); }
@Test public void testPerThisAspect() throws SecurityException, NoSuchMethodException { TestBean target = new TestBean(); int realAge = 65; target.setAge(realAge); TestBean itb = (TestBean) createProxy(target, getFixture().getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(new PerThisAspect(), "someBean")), TestBean.class); assertEquals("Around advice must NOT apply", realAge, itb.getAge()); Advised advised = (Advised) itb; // Will be ExposeInvocationInterceptor, synthetic instantiation advisor, 2 method advisors assertEquals(4, advised.getAdvisors().length); ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor sia = (ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor) advised.getAdvisors()[1]; assertTrue(sia.getPointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null)); InstantiationModelAwarePointcutAdvisorImpl imapa = (InstantiationModelAwarePointcutAdvisorImpl) advised.getAdvisors()[2]; LazySingletonAspectInstanceFactoryDecorator maaif = (LazySingletonAspectInstanceFactoryDecorator) imapa.getAspectInstanceFactory(); assertFalse(maaif.isMaterialized()); // Check that the perclause pointcut is valid assertTrue(maaif.getAspectMetadata().getPerClausePointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null)); assertNotSame(imapa.getDeclaredPointcut(), imapa.getPointcut()); // Hit the method in the per clause to instantiate the aspect itb.getSpouse(); assertTrue(maaif.isMaterialized()); assertTrue(imapa.getDeclaredPointcut().getMethodMatcher().matches(TestBean.class.getMethod("getAge"), null)); assertEquals("Around advice must apply", 0, itb.getAge()); assertEquals("Around advice must apply", 1, itb.getAge()); }
@Test public void testPerTargetAspect() throws SecurityException, NoSuchMethodException { ClassPathXmlApplicationContext bf = newContext("pertarget.xml"); ITestBean adrian1 = (ITestBean) bf.getBean("adrian"); assertTrue(AopUtils.isAopProxy(adrian1)); // Does not trigger advice or count int explicitlySetAge = 25; adrian1.setAge(explicitlySetAge); assertEquals("Setter does not initiate advice", explicitlySetAge, adrian1.getAge()); // Fire aspect AspectMetadata am = new AspectMetadata(PerTargetAspect.class, "someBean"); assertTrue(am.getPerClausePointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null)); adrian1.getSpouse(); assertEquals("Advice has now been instantiated", 0, adrian1.getAge()); adrian1.setAge(11); assertEquals("Any int setter increments", 2, adrian1.getAge()); adrian1.setName("Adrian"); //assertEquals("Any other setter does not increment", 2, adrian1.getAge()); ITestBean adrian2 = (ITestBean) bf.getBean("adrian"); assertNotSame(adrian1, adrian2); assertTrue(AopUtils.isAopProxy(adrian1)); assertEquals(34, adrian2.getAge()); adrian2.getSpouse(); assertEquals("Aspect now fired", 0, adrian2.getAge()); assertEquals(1, adrian2.getAge()); assertEquals(2, adrian2.getAge()); assertEquals(3, adrian1.getAge()); }
ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor sia = (ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor) advised.getAdvisors()[1]; assertTrue(sia.getPointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null)); InstantiationModelAwarePointcutAdvisorImpl imapa = (InstantiationModelAwarePointcutAdvisorImpl) advised.getAdvisors()[2]; LazySingletonAspectInstanceFactoryDecorator maaif = assertTrue(maaif.getAspectMetadata().getPerClausePointcut().getMethodMatcher().matches(TestBean.class.getMethod("getSpouse"), null)); assertNotSame(imapa.getDeclaredPointcut(), imapa.getPointcut());
public boolean matches(Method method, Class targetClass, Object[] args) { // 2-arg matcher will already have run, so we don't need to do class filtering again. return a.getMethodMatcher().matches(method, targetClass, args) || b.getMethodMatcher().matches(method, targetClass, args); } }