@Before @PostConstruct Spring AOP ineterception

时间:2017-02-16 09:56:08

标签: spring aop aspectj postconstruct

我试图编写一个可以拦截PostConstruct方法的方面。我已经看过关于SO和其他人的相关问题,并且关注它们,这是我到目前为止所做的:

Spring配置

@Configuration
@EnableAspectJAutoProxy
@EnableLoadTimeWeaving
@...//other config annotations
public class WebConfiguration {

    @Bean
    public CommonAnnotationBeanPostProcessor commonAnnotationBeanPostProcessor() {
        return new CommonAnnotationBeanPostProcessor();
    }
    ... // etc

}

注释:

@Retention(RetentionPolicy.RUNTIME)
public @interface Secured {
    Permission[] permissions() default {};
}

@Component
@Scope("request")
public class SomeWebBean {

    @Secured(permissions = Permission.SOME_PERMISSION)
    @PostConstruct
    public void secure() {
        ... // some stuff
    }

}

方面

@Component
@Aspect
public class SecuredAspect {

    @Before("@annotation(secured)")
    public void doAccessCheck(Secured secured) {
        ... // actually do the access check
    }

}

如果我从某个页面调用someWebBean.secure(),则会调用该方面。但是,它不会在bean创建时调用。

2 个答案:

答案 0 :(得分:1)

所以作为对未来我的一个注意事项 - 使用Spring AOP绝对不能以这种方式完成。

但是,通过实现如下的BeanPostProcessor可以实现相同的效果:

public class SecureBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Secured secured = bean.getClass().getAnnotation(Secured.class);
        if (secured != null) {
            // do your security test here, throw an exception, return false, however you like
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

答案 1 :(得分:0)

您可以扩展CommonAnnotationBeanPostProcessor并覆盖postProcessBeforeInitialization(Object bean,String beanName)

然后注册用BeanFactoryPostProcessor替换原始的CommonAnnotationBeanPostProcessor。

public class InitCommonAnnotationBeanPostProcessor extends CommonAnnotationBeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return super.postProcessBeforeInitialization(bean, beanName);
    }
}


public class InitBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        RootBeanDefinition def = new RootBeanDefinition(InitCommonAnnotationBeanPostProcessor.class);
        def.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        registry.registerBeanDefinition(AnnotationConfigUtils.COMMON_ANNOTATION_PROCESSOR_BEAN_NAME, def);
    }
}



@Configuration
public class InitialisationMonitoringConfig {

    public static final String BEAN_INIT_MONITOR = "BEAN_INIT_MONITOR";

    @Bean
    public static InitBeanFactoryPostProcessor initBeanFactoryPostProcessor() {
        return new InitBeanFactoryPostProcessor();
    }

}

这很难看,但我必须这样做来分析开发环境中的启动时间。

也许它足以将InitCommonAnnotationBeanPostProcessor声明为bean,我没有尝试过。