在Spring Boot中哪里写通用代码

时间:2018-11-12 16:06:13

标签: spring spring-mvc spring-boot

我想编写应该在每种方法之前执行的通用代码, 我可以在春天在哪里放置此代码。

谢谢。

2 个答案:

答案 0 :(得分:0)

您应该看看Spring AOP。使用Spring AOP,您可以编写Aspects,它可以是在方法之前/之后执行的通用代码。以下示例是一个简单的方面:

@Aspect
public class EmployeeAspect {

    @Before("execution(public String getName())")
    public void getNameAdvice(){
        System.out.println("Executing Advice on getName()");
    }

    @Before("execution(* your.package.name.*.get*())")
    public void getAllAdvice(){
        System.out.println("Service method getter called");
    }
}

@Before()批注中,您可以指定Aspect包围的确切方法,也可以使用通配符*指定更多方法。为此,您应该熟悉Pointcut expressions

答案 1 :(得分:0)

您要问的不是琐碎的,而是面向方面的编程(AoP)是实现这一目标的一种方法。此描述假定您总体上对Proxy类,InvocationHandler接口和Interceptor模式有所了解。正如我所说,这不是一件小事。

  1. 在每个方法或某个方法或任何方法之前定义要执行的逻辑。通常是某种拦截器,这是一个示例:

    public class TimeProfilerInterceptor implements MethodInterceptor {
    
        @Getter
        private final TimeStatistics statistics = new TimeStatistics();
    
        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
            StopWatch watch = new StopWatch();
            try {
                watch.start();
                Object returnValue = invocation.proceed();
                return returnValue;
            }
            finally {
                // etc...
            }
        }
    }
    
  2. 定义逻辑连接到方法的位置。在此示例中,该位置是Spring组件,该组件扩展了AbstractBeanFactoryAwareAdvisingPostProcessor并实现了InitializingBean。 Bean初始化完成后,Spring将调用afterPropertiesSet方法。该方法使用Advice中的spring-aop类来标识切入点,即拦截器必须包装的方法。在这种情况下,它是一个基于注释的切入点,这意味着它与上面具有特定自定义注释(TimeProfiled)的每个方法匹配。

    @Component
    public class TimeProfiledAnnotationPostProcessor 
            extends AbstractBeanFactoryAwareAdvisingPostProcessor 
            implements InitializingBean {
    
        @Autowired
        TimeProfilerInterceptor timeProfilerInterceptor;
    
        @Override
        public void afterPropertiesSet() throws Exception {
            this.setProxyTargetClass(true);
            Advice advice = timeProfilerInterceptor;
            Pointcut pointcut = new AnnotationMatchingPointcut(null, TimeProfiled.class);
            this.advisor = new DefaultPointcutAdvisor(pointcut, advice);
        }
    }
    
  3. 定义您的自定义注释以在需要的地方使用。

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface TimeProfiled {
    
    }
    
  4. 告诉Spring在启动时通过Spring Configuration或SpringBootApplication上的以下注释启动包装机制:

    @ComponentScan(basePackageClasses = TimeProfiledAnnotationPostProcessor.class)
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    

您可以更改切入点,以使其与其他方法和其他条件匹配,这是一个完整的语法,这本身就是一个世界,这只是一个小例子...