From d06d202fd095d07ff48a8f7e8c68cd7477f56490 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 11 Sep 2013 05:14:49 -0700 Subject: [PATCH] Add AopAutoConfiguration (also starter and sample) A side effect is that spring-boot-starter-data-jpa needs to include an aspectjweaver depdendency. Hope that doesn't hurt anything else. [Fixes #56780004] --- .../aop/AopAutoConfiguration.java | 50 +++++++++++++ .../main/resources/META-INF/spring.factories | 1 + spring-boot-samples/pom.xml | 1 + .../spring-boot-sample-aop/pom.xml | 30 ++++++++ .../boot/sample/aop/SampleAopApplication.java | 45 ++++++++++++ .../sample/aop/monitor/ServiceMonitor.java | 17 +++++ .../sample/aop/service/HelloWorldService.java | 32 +++++++++ .../src/main/resources/application.properties | 1 + .../sample/aop/SampleAopApplicationTests.java | 70 +++++++++++++++++++ spring-boot-starters/pom.xml | 1 + .../spring-boot-starter-aop/.gitignore | 1 + .../spring-boot-starter-aop/pom.xml | 34 +++++++++ .../spring-boot-starter-data-jpa/pom.xml | 6 +- .../spring-boot-starter-parent/pom.xml | 5 ++ 14 files changed, 289 insertions(+), 5 deletions(-) create mode 100644 spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/aop/AopAutoConfiguration.java create mode 100644 spring-boot-samples/spring-boot-sample-aop/pom.xml create mode 100644 spring-boot-samples/spring-boot-sample-aop/src/main/java/org/springframework/boot/sample/aop/SampleAopApplication.java create mode 100644 spring-boot-samples/spring-boot-sample-aop/src/main/java/org/springframework/boot/sample/aop/monitor/ServiceMonitor.java create mode 100644 spring-boot-samples/spring-boot-sample-aop/src/main/java/org/springframework/boot/sample/aop/service/HelloWorldService.java create mode 100644 spring-boot-samples/spring-boot-sample-aop/src/main/resources/application.properties create mode 100644 spring-boot-samples/spring-boot-sample-aop/src/test/java/org/springframework/boot/sample/aop/SampleAopApplicationTests.java create mode 100644 spring-boot-starters/spring-boot-starter-aop/.gitignore create mode 100644 spring-boot-starters/spring-boot-starter-aop/pom.xml diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/aop/AopAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/aop/AopAutoConfiguration.java new file mode 100644 index 00000000000..6e37281153d --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/aop/AopAutoConfiguration.java @@ -0,0 +1,50 @@ +/* + * Copyright 2012-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.aop; + +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.Advice; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.EnableAspectJAutoProxy; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Spring AOP. + * + * @author Dave Syer + * @see EnableAspectJAutoProxy + */ +@Configuration +@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class }) +@ConditionalOnExpression("${spring.aop.auto:true}") +public class AopAutoConfiguration { + + @Configuration + @EnableAspectJAutoProxy(proxyTargetClass = false) + @ConditionalOnExpression("!${spring.aop.proxyTargetClass:false}") + public static class JdkDynamicAutoProxyConfiguration { + } + + @Configuration + @EnableAspectJAutoProxy(proxyTargetClass = true) + @ConditionalOnExpression("${spring.aop.proxyTargetClass:false}") + public static class CglibAutoProxyConfiguration { + } + +} diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index 1c157bdde39..106c3316a54 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -1,5 +1,6 @@ # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration,\ org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\ diff --git a/spring-boot-samples/pom.xml b/spring-boot-samples/pom.xml index 40ac1b86aff..f837e75404b 100644 --- a/spring-boot-samples/pom.xml +++ b/spring-boot-samples/pom.xml @@ -16,6 +16,7 @@ spring-boot-sample-actuator spring-boot-sample-actuator-ui + spring-boot-sample-aop spring-boot-sample-batch spring-boot-sample-data-jpa spring-boot-sample-integration diff --git a/spring-boot-samples/spring-boot-sample-aop/pom.xml b/spring-boot-samples/spring-boot-sample-aop/pom.xml new file mode 100644 index 00000000000..b19e87577bb --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-aop/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-samples + 0.5.0.BUILD-SNAPSHOT + + spring-boot-sample-aop + jar + + ${basedir}/../.. + + + + ${project.groupId} + spring-boot-starter-aop + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/spring-boot-samples/spring-boot-sample-aop/src/main/java/org/springframework/boot/sample/aop/SampleAopApplication.java b/spring-boot-samples/spring-boot-sample-aop/src/main/java/org/springframework/boot/sample/aop/SampleAopApplication.java new file mode 100644 index 00000000000..881f6cb05f7 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-aop/src/main/java/org/springframework/boot/sample/aop/SampleAopApplication.java @@ -0,0 +1,45 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.sample.aop; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.sample.aop.service.HelloWorldService; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan +public class SampleAopApplication implements CommandLineRunner { + + // Simple example shows how an application can spy on itself with AOP + + @Autowired + private HelloWorldService helloWorldService; + + @Override + public void run(String... args) { + System.out.println(this.helloWorldService.getHelloMessage()); + } + + public static void main(String[] args) throws Exception { + SpringApplication.run(SampleAopApplication.class, args); + } +} diff --git a/spring-boot-samples/spring-boot-sample-aop/src/main/java/org/springframework/boot/sample/aop/monitor/ServiceMonitor.java b/spring-boot-samples/spring-boot-sample-aop/src/main/java/org/springframework/boot/sample/aop/monitor/ServiceMonitor.java new file mode 100644 index 00000000000..60be6e78064 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-aop/src/main/java/org/springframework/boot/sample/aop/monitor/ServiceMonitor.java @@ -0,0 +1,17 @@ +package org.springframework.boot.sample.aop.monitor; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +@Aspect +@Component +public class ServiceMonitor { + + @AfterReturning("execution(* *..*Service.*(..))") + public void logServiceAccess(JoinPoint joinPoint) { + System.out.println("Completed: " + joinPoint); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-aop/src/main/java/org/springframework/boot/sample/aop/service/HelloWorldService.java b/spring-boot-samples/spring-boot-sample-aop/src/main/java/org/springframework/boot/sample/aop/service/HelloWorldService.java new file mode 100644 index 00000000000..22d662aeb82 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-aop/src/main/java/org/springframework/boot/sample/aop/service/HelloWorldService.java @@ -0,0 +1,32 @@ +/* + * Copyright 2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.sample.aop.service; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class HelloWorldService { + + @Value("${name:World}") + private String name; + + public String getHelloMessage() { + return "Hello " + this.name; + } + +} diff --git a/spring-boot-samples/spring-boot-sample-aop/src/main/resources/application.properties b/spring-boot-samples/spring-boot-sample-aop/src/main/resources/application.properties new file mode 100644 index 00000000000..4dfe84cedc6 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-aop/src/main/resources/application.properties @@ -0,0 +1 @@ +name: Phil \ No newline at end of file diff --git a/spring-boot-samples/spring-boot-sample-aop/src/test/java/org/springframework/boot/sample/aop/SampleAopApplicationTests.java b/spring-boot-samples/spring-boot-sample-aop/src/test/java/org/springframework/boot/sample/aop/SampleAopApplicationTests.java new file mode 100644 index 00000000000..4c56bcdea98 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-aop/src/test/java/org/springframework/boot/sample/aop/SampleAopApplicationTests.java @@ -0,0 +1,70 @@ +/* + * Copyright 2012-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.sample.aop; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.springframework.boot.OutputCapture; +import org.springframework.boot.sample.aop.SampleAopApplication; + +import static org.junit.Assert.assertTrue; + +/** + * Tests for {@link SampleAopApplication}. + * + * @author Dave Syer + * @author Phillip Webb + */ +public class SampleAopApplicationTests { + + @Rule + public OutputCapture outputCapture = new OutputCapture(); + + private String profiles; + + @Before + public void init() { + this.profiles = System.getProperty("spring.profiles.active"); + } + + @After + public void after() { + if (this.profiles != null) { + System.setProperty("spring.profiles.active", this.profiles); + } + else { + System.clearProperty("spring.profiles.active"); + } + } + + @Test + public void testDefaultSettings() throws Exception { + SampleAopApplication.main(new String[0]); + String output = this.outputCapture.toString(); + assertTrue("Wrong output: " + output, output.contains("Hello Phil")); + } + + @Test + public void testCommandLineOverrides() throws Exception { + SampleAopApplication.main(new String[] { "--name=Gordon" }); + String output = this.outputCapture.toString(); + assertTrue("Wrong output: " + output, output.contains("Hello Gordon")); + } + +} diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml index ebc83a2c81b..b3d5a50e833 100644 --- a/spring-boot-starters/pom.xml +++ b/spring-boot-starters/pom.xml @@ -15,6 +15,7 @@ spring-boot-starter + spring-boot-starter-aop spring-boot-starter-batch spring-boot-starter-data-jpa spring-boot-starter-integration diff --git a/spring-boot-starters/spring-boot-starter-aop/.gitignore b/spring-boot-starters/spring-boot-starter-aop/.gitignore new file mode 100644 index 00000000000..ea8c4bf7f35 --- /dev/null +++ b/spring-boot-starters/spring-boot-starter-aop/.gitignore @@ -0,0 +1 @@ +/target diff --git a/spring-boot-starters/spring-boot-starter-aop/pom.xml b/spring-boot-starters/spring-boot-starter-aop/pom.xml new file mode 100644 index 00000000000..b2eed51f0f0 --- /dev/null +++ b/spring-boot-starters/spring-boot-starter-aop/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starters + 0.5.0.BUILD-SNAPSHOT + + spring-boot-starter-aop + jar + + ${basedir}/../.. + + + + ${project.groupId} + spring-boot-starter + ${project.version} + + + org.springframework + spring-aop + + + org.aspectj + aspectjrt + + + org.aspectj + aspectjweaver + + + diff --git a/spring-boot-starters/spring-boot-starter-data-jpa/pom.xml b/spring-boot-starters/spring-boot-starter-data-jpa/pom.xml index 2d154930aea..91dd194f019 100644 --- a/spring-boot-starters/spring-boot-starter-data-jpa/pom.xml +++ b/spring-boot-starters/spring-boot-starter-data-jpa/pom.xml @@ -15,17 +15,13 @@ ${project.groupId} - spring-boot-starter + spring-boot-starter-aop ${project.version} org.hibernate hibernate-entitymanager - - org.springframework - spring-aop - org.springframework spring-orm diff --git a/spring-boot-starters/spring-boot-starter-parent/pom.xml b/spring-boot-starters/spring-boot-starter-parent/pom.xml index a0011a2429d..a4bb0c7ce54 100644 --- a/spring-boot-starters/spring-boot-starter-parent/pom.xml +++ b/spring-boot-starters/spring-boot-starter-parent/pom.xml @@ -42,6 +42,11 @@ spring-boot-starter 0.5.0.BUILD-SNAPSHOT + + org.springframework.boot + spring-boot-starter-aop + 0.5.0.BUILD-SNAPSHOT + org.springframework.boot spring-boot-starter-actuator