在上一篇文章中,我提供了一个有关如何通过使用ProxyFactoryBean并实现MethodBeforeAdvice接口在Spring实现宽高比定向的简单示例。
在此示例中,我们将学习如何通过使用Spring Boot和Aspect4j注释来实现方面方向。
让我们从gradle文件开始。
group 'com.gkatzioura'
version '1.0-SNAPSHOT'apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'spring-boot'sourceCompatibility = 1.8buildscript {repositories {mavenCentral()}dependencies {classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.3.RELEASE")}
}repositories {mavenCentral()
}dependencies {compile("org.springframework.boot:spring-boot-starter-web") {exclude module: "spring-boot-starter-tomcat"}compile("org.springframework.boot:spring-boot-starter-jetty")compile("org.slf4j:slf4j-api:1.6.6")compile("ch.qos.logback:logback-classic:1.0.13")compile("org.aspectj:aspectjweaver:1.8.8")testCompile("junit:junit:4.11")
}
除了Spring Boot插件外,我们还必须包括AspectJweaver软件包。
应用类别
package com.gkatzioura.spring.aop;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;/*** Created by gkatzioura on 5/28/16.*/
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication springApplication = new SpringApplication();ApplicationContext applicationContext = springApplication.run(Application.class,args);}
}
我们将实现一项服务,该服务将获取指定名称的示例。
样本模型将是一个简单的pojo
package com.gkatzioura.spring.aop.model;/*** Created by gkatzioura on 5/28/16.*/
public class Sample {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
该服务将创建一个示例对象。
package com.gkatzioura.spring.aop.service;import com.gkatzioura.spring.aop.model.Sample;
import org.springframework.stereotype.Service;/*** Created by gkatzioura on 5/28/16.*/
@Service
public class SampleService {public Sample createSample(String sampleName) {Sample sample = new Sample();sample.setName(sampleName);return sample;}
}
到目前为止,一切都很好。 假设我们要在创建样本之前和之后执行一些操作。 Spring的AOP可以帮助我们做到这一点。
createSample函数是一个JoinPoint。 主要概念是与建议一起使用。 根据文档建议,是方面在特定的连接点处采取的措施。
在我们的例子中,我们想在创建样本之前做一些额外的日志记录。 因此,我们将使用之前建议类型。
package com.gkatzioura.spring.aop.aspect;import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;/*** Created by gkatzioura on 5/28/16.*/
@Aspect
@Component
public class SampleServiceAspect {private static final Logger LOGGER = LoggerFactory.getLogger(SampleServiceAspect.class);@Before("execution(* com.gkatzioura.spring.aop.service.SampleService.createSample (java.lang.String)) && args(sampleName)")public void beforeSampleCreation(String sampleName) {LOGGER.info("A request was issued for a sample name: "+sampleName);}}
我们使用@Before注释实现了一个函数。 我们提供给注解的参数是切入点表达式。 切入点表达式可帮助我们定义函数,这将触发我们的建议和应使用的函数参数。 因此,在执行createSample方法之前,应该在屏幕上显示一条日志消息。
假设我们要在执行该方法之前和之后采取更多措施,甚至更改createSample函数的结果,我们可以使用@Around Advice。
package com.gkatzioura.spring.aop.aspect;import com.gkatzioura.spring.aop.model.Sample;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;/*** Created by gkatzioura on 5/28/16.*/
@Aspect
@Component
public class SampleServiceAspect {private static final Logger LOGGER = LoggerFactory.getLogger(SampleServiceAspect.class);@Before("execution(* com.gkatzioura.spring.aop.service.SampleService.createSample (java.lang.String)) && args(sampleName)")public void beforeSampleCreation(String sampleName) {LOGGER.info("A request was issued for a sample name: "+sampleName);}@Around("execution(* com.gkatzioura.spring.aop.service.SampleService.createSample (java.lang.String)) && args(sampleName)")public Object aroundSampleCreation(ProceedingJoinPoint proceedingJoinPoint,String sampleName) throws Throwable {LOGGER.info("A request was issued for a sample name: "+sampleName);sampleName = sampleName+"!";Sample sample = (Sample) proceedingJoinPoint.proceed(new Object[] {sampleName});sample.setName(sample.getName().toUpperCase());return sample;}}
正如我们所看到的aroundSampleCreation建议一样,更改输入并更改结果。 您可以在github上找到源代码
翻译自: https://www.javacodegeeks.com/2016/05/aspect-oriented-programming-spring-boot.html