cleaned up AOP usage

This commit is contained in:
Mic 2013-02-08 12:46:00 +08:00
parent 0e60b03708
commit 5699bf83ee
28 changed files with 95 additions and 1273 deletions

View file

@ -8,7 +8,26 @@
<enableImports><![CDATA[false]]></enableImports>
<configs>
<config>src/main/webapp/WEB-INF/mvc-core-config.xml</config>
<config>src/main/webapp/WEB-INF/mvc-view-config.xml</config>
<config>src/main/resources/spring/dao-config.xml</config>
<config>src/main/resources/spring/datasource-config.xml</config>
<config>src/main/resources/spring/service-config.xml</config>
</configs>
<configSets>
<configSet>
<name><![CDATA[config]]></name>
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>
<incomplete>false</incomplete>
<configs>
<config>src/main/webapp/WEB-INF/mvc-core-config.xml</config>
<config>src/main/webapp/WEB-INF/mvc-view-config.xml</config>
<config>src/main/resources/spring/dao-config.xml</config>
<config>src/main/resources/spring/datasource-config.xml</config>
<config>src/main/resources/spring/jmx-aop-config.xml</config>
<config>src/main/resources/spring/service-config.xml</config>
</configs>
<profiles>
</profiles>
</configSet>
</configSets>
</beansProjectDescription>

View file

@ -2,8 +2,10 @@ package org.springframework.samples.petclinic.aspects;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.util.StopWatch;
/**
@ -12,10 +14,11 @@ import org.springframework.util.StopWatch;
*
* @author Rob Harrop
* @author Juergen Hoeller
* @author Michael Isvy
* @since 2.5
*/
//@ManagedResource("petclinic:type=CallMonitor")
//@Aspect
@ManagedResource("petclinic:type=CallMonitor")
@Aspect
public class CallMonitoringAspect {
private boolean isEnabled = true;

View file

@ -1,48 +0,0 @@
package org.springframework.samples.petclinic.aspects;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* Sample AspectJ annotation-style aspect that saves
* every owner name requested to the petRepository.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
*/
@Aspect
public class UsageLogAspect {
private int historySize = 100;
// Of course saving all names is not suitable for
// production use, but this is a simple example.
private List<String> namesRequested = new ArrayList<String>(this.historySize);
public synchronized void setHistorySize(int historySize) {
this.historySize = historySize;
this.namesRequested = new ArrayList<String>(historySize);
}
@Before("execution(* *.find*(String)) && args(name)")
public synchronized void logNameRequest(String name) {
// Not the most efficient implementation,
// but we're aiming to illustrate the power of
// @AspectJ AOP, not write perfect code here :-)
if (this.namesRequested.size() > this.historySize) {
this.namesRequested.remove(0);
}
this.namesRequested.add(name);
}
public synchronized List<String> getNamesRequested() {
return Collections.unmodifiableList(this.namesRequested);
}
}

View file

@ -22,7 +22,7 @@ import org.springframework.samples.petclinic.Visit;
import org.springframework.samples.petclinic.repository.OwnerRepository;
import org.springframework.samples.petclinic.repository.VisitRepository;
import org.springframework.samples.petclinic.util.EntityUtils;
import org.springframework.stereotype.Service;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
/**
@ -36,7 +36,7 @@ import org.springframework.transaction.annotation.Transactional;
* @author Thomas Risberg
* @author Mark Fisher
*/
@Service
@Repository
public class JdbcOwnerRepositoryImpl implements OwnerRepository {
private VisitRepository visitRepository;

View file

@ -18,7 +18,7 @@ import org.springframework.samples.petclinic.Specialty;
import org.springframework.samples.petclinic.Vet;
import org.springframework.samples.petclinic.repository.VetRepository;
import org.springframework.samples.petclinic.util.EntityUtils;
import org.springframework.stereotype.Service;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
/**
@ -30,7 +30,7 @@ import org.springframework.transaction.annotation.Transactional;
* @author Thomas Risberg
* @author Mark Fisher
*/
@Service
@Repository
public class JdbcVetRepositoryImpl implements VetRepository {
private final Logger logger = LoggerFactory.getLogger(getClass());

View file

@ -17,7 +17,7 @@ import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.samples.petclinic.Visit;
import org.springframework.samples.petclinic.repository.VisitRepository;
import org.springframework.samples.petclinic.service.ClinicService;
import org.springframework.stereotype.Service;
import org.springframework.stereotype.Repository;
/**
* A simple JDBC-based implementation of the {@link ClinicService} interface.
@ -31,7 +31,7 @@ import org.springframework.stereotype.Service;
* @author Mark Fisher
* @author Michael Isvy
*/
@Service
@Repository
public class JdbcVisitRepositoryImpl implements VisitRepository {
private JdbcTemplate jdbcTemplate;

View file

@ -3,19 +3,17 @@
Application context definition for PetClinic on JPA.
-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.1.xsd
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- ========================= RESOURCE DEFINITIONS ========================= -->
<!-- import the dataSource definition -->
<import resource="applicationContext-dataSource.xml"/>
<import resource="datasource-config.xml"/>
<!-- Configurer that replaces ${...} placeholders with values from a properties file -->
@ -40,28 +38,6 @@
-->
<tx:annotation-driven/>
<!--
Simply defining this bean will cause requests to owner names to be saved.
This aspect is defined in petclinic.jar's META-INF/aop.xml file.
Note that we can dependency inject this bean like any other bean.
-->
<aop:aspectj-autoproxy>
<aop:include name="usageLogAspect"/>
<aop:include name="callMonitor"/>
</aop:aspectj-autoproxy>
<bean id="usageLogAspect" class="org.springframework.samples.petclinic.aspects.UsageLogAspect" p:historySize="300"/>
<!-- Call monitoring aspect that monitors call count and call invocation time -->
<bean id="callMonitor" class="org.springframework.samples.petclinic.aspects.CallMonitoringAspect"/>
<!--
Exporter that exposes the Clinic DAO and the CallMonitoringAspect via JMX,
based on the @ManagedResource, @ManagedAttribute, and @ManagedOperation annotations.
-->
<context:mbean-export/>
<beans profile="jpa,spring-data-jpa">
<!-- JPA EntityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Application context definition for PetClinic on JPA.
-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--
Simply defining this bean will cause requests to owner names to be saved.
This aspect is defined in petclinic.jar's META-INF/aop.xml file.
Note that we can dependency inject this bean like any other bean.
-->
<aop:aspectj-autoproxy>
<aop:include name="callMonitor"/>
</aop:aspectj-autoproxy>
<!-- Call monitoring aspect that monitors call count and call invocation time -->
<bean id="callMonitor" class="org.springframework.samples.petclinic.aspects.CallMonitoringAspect"/>
<!--
Exporter that exposes the CallMonitoringAspect via JMX,
based on the @ManagedResource, @ManagedAttribute, and @ManagedOperation annotations.
-->
<context:mbean-export />
</beans>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Application context definition for PetClinic on JPA.
-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="org.springframework.samples.petclinic.service"/>
</beans>

View file

@ -8,9 +8,9 @@
<ul class="nav">
<li style="width: 100px;"><a href="<spring:url value="/" htmlEscape="true" />"><i class="icon-home"></i> Home</a></li>
<li style="width: 130px;"><a href="<spring:url value="/owners/find.html" htmlEscape="true" />"><i class="icon-search"></i> Find owners</a></li>
<li style="width: 130px;"><a href="<spring:url value="/vets.html" htmlEscape="true" />"><i class="icon-th-list"></i> Veterinarians</a></li>
<li style="width: 100px;"><a href="<spring:url value="/resources/html/tutorial.html" htmlEscape="true" />"><i class=" icon-question-sign"></i> Tutorial</a></li>
<li style="width: 80px;"><a href="<spring:url value="/oups.html" htmlEscape="true" />" title="trigger a RuntimeException to see how it is handled"><i class="icon-warning-sign"></i> Error</a></li>
<li style="width: 140px;"><a href="<spring:url value="/vets.html" htmlEscape="true" />"><i class="icon-th-list"></i> Veterinarians</a></li>
<li style="width: 90px;"><a href="<spring:url value="/oups.html" htmlEscape="true" />" title="trigger a RuntimeException to see how it is handled"><i class="icon-warning-sign"></i> Error</a></li>
<li style="width: 80px;"><a href="#" title="not available yet. Work in progress!!"><i class=" icon-question-sign"></i> Help</a></li>
</ul>
</div>
</div>

View file

@ -15,7 +15,7 @@
<!--
- POJOs labeled with the @Controller and @Service annotations are auto-detected.
-->
<context:component-scan base-package="org.springframework.samples.petclinic.web, org.springframework.samples.petclinic.service"/>
<context:component-scan base-package="org.springframework.samples.petclinic.web"/>
<mvc:annotation-driven conversion-service="conversionService"/>

View file

@ -23,7 +23,7 @@ id="WebApp_ID" version="2.5">
-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-dao.xml</param-value>
<param-value>classpath:spring/dao-config.xml, classpath:spring/service-config.xml, classpath:spring/jmx-aop-config.xml</param-value>
</context-param>
<listener>

File diff suppressed because it is too large Load diff

View file

@ -1,56 +0,0 @@
package org.springframework.samples.petclinic.aspects;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.samples.petclinic.repository.OwnerRepository;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* <p>
* Tests for the DAO variant based on the shared EntityManager approach. Uses
* TopLink Essentials (the reference implementation) for testing.
* </p>
* <p>
* Specifically tests usage of an <code>orm.xml</code> file, loaded by the
* persistence provider through the Spring-provided persistence unit root URL.
* </p>
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
@ContextConfiguration(locations={"classpath:spring/applicationContext-dao.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles({"jpa","plain-jpa"})
public class UsageLogAspectTests {
@Autowired
private UsageLogAspect usageLogAspect;
@Autowired
private OwnerRepository ownerRepository;
@Test
public void testUsageLogAspectIsInvoked() {
String lastName1 = "Franklin";
String lastName2 = "Davis";
String lastName3 = "foo";
assertFalse(this.ownerRepository.findByLastName(lastName1).isEmpty());
assertFalse(this.ownerRepository.findByLastName(lastName2).isEmpty());
List<String> namesRequested = this.usageLogAspect.getNamesRequested();
assertTrue(namesRequested.contains(lastName1));
assertTrue(namesRequested.contains(lastName2));
assertFalse(namesRequested.contains(lastName3));
}
}

View file

@ -16,7 +16,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author Thomas Risberg
* @author Michael Isvy
*/
@ContextConfiguration(locations={"classpath:spring/applicationContext-dao.xml"})
@ContextConfiguration(locations={"classpath:spring/dao-config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("jdbc")
public class JdbcOwnerRepositoryImplTests extends AbstractOwnerRepositoryTests {

View file

@ -16,7 +16,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author Thomas Risberg
* @author Michael Isvy
*/
@ContextConfiguration(locations={"classpath:spring/applicationContext-dao.xml"})
@ContextConfiguration(locations={"classpath:spring/dao-config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("jdbc")
public class JdbcPetRepositoryImplTests extends AbstractPetRepositoryTests {

View file

@ -16,7 +16,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author Thomas Risberg
* @author Michael Isvy
*/
@ContextConfiguration(locations={"classpath:spring/applicationContext-dao.xml"})
@ContextConfiguration(locations={"classpath:spring/dao-config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("jdbc")
public class JdbcVetRepositoryImplTests extends AbstractVetRepositoryTests {

View file

@ -16,7 +16,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author Thomas Risberg
* @author Michael Isvy
*/
@ContextConfiguration(locations={"classpath:spring/applicationContext-dao.xml"})
@ContextConfiguration(locations={"classpath:spring/dao-config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("jdbc")
public class JdbcVisitRepositoryImplTests extends AbstractVisitRepositoryTests {

View file

@ -26,7 +26,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author Michael Isvy
*/
@ContextConfiguration(locations={"classpath:spring/applicationContext-dao.xml"})
@ContextConfiguration(locations={"classpath:spring/dao-config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("jpa")
public class JpaOwnerRepositoryImplTests extends AbstractOwnerRepositoryTests {

View file

@ -16,7 +16,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author Thomas Risberg
* @author Michael Isvy
*/
@ContextConfiguration(locations={"classpath:spring/applicationContext-dao.xml"})
@ContextConfiguration(locations={"classpath:spring/dao-config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("jpa")
public class JpaPetRepositoryImplTests extends AbstractPetRepositoryTests {

View file

@ -16,7 +16,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author Thomas Risberg
* @author Michael Isvy
*/
@ContextConfiguration(locations={"classpath:spring/applicationContext-dao.xml"})
@ContextConfiguration(locations={"classpath:spring/dao-config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("jpa")
public class JpaVetRepositoryImplTests extends AbstractVetRepositoryTests {

View file

@ -16,7 +16,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author Thomas Risberg
* @author Michael Isvy
*/
@ContextConfiguration(locations={"classpath:spring/applicationContext-dao.xml"})
@ContextConfiguration(locations={"classpath:spring/dao-config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("jpa")
public class JpaVisitRepositoryImplTests extends AbstractVisitRepositoryTests {

View file

@ -26,7 +26,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author Michael Isvy
*/
@ContextConfiguration(locations={"classpath:spring/applicationContext-dao.xml"})
@ContextConfiguration(locations={"classpath:spring/dao-config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("spring-data-jpa")
public class JpaOwnerRepositoryImplTests extends AbstractOwnerRepositoryTests {

View file

@ -16,7 +16,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author Thomas Risberg
* @author Michael Isvy
*/
@ContextConfiguration(locations={"classpath:spring/applicationContext-dao.xml"})
@ContextConfiguration(locations={"classpath:spring/dao-config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("spring-data-jpa")
public class JpaPetRepositoryImplTests extends AbstractPetRepositoryTests {

View file

@ -16,7 +16,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author Thomas Risberg
* @author Michael Isvy
*/
@ContextConfiguration(locations={"classpath:spring/applicationContext-dao.xml"})
@ContextConfiguration(locations={"classpath:spring/dao-config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("spring-data-jpa")
public class JpaVetRepositoryImplTests extends AbstractVetRepositoryTests {

View file

@ -16,7 +16,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author Thomas Risberg
* @author Michael Isvy
*/
@ContextConfiguration(locations={"classpath:spring/applicationContext-dao.xml"})
@ContextConfiguration(locations={"classpath:spring/dao-config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("spring-data-jpa")
public class JpaVisitRepositoryImplTests extends AbstractVisitRepositoryTests {

View file

@ -11,7 +11,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author Michael Isvy
*/
@ContextConfiguration(locations={"classpath:spring/applicationContext-dao.xml"})
@ContextConfiguration(locations={"classpath:spring/dao-config.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("spring-data-jpa")
public class SpringDataOwnerRepositoryTests extends AbstractOwnerRepositoryTests {