--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>de.spring.example</groupId>
+ <artifactId>spring-aop-example</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <name>spring-aop-example</name>
+ <url>http://gumartinm.name</url>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aspects</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aop</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>cglib</groupId>
+ <artifactId>cglib</artifactId>
+ <version>3.2.1</version>
+ </dependency>
+
+ <!--
+ 1/3 Required dependency for log4j 2 with slf4j: binding between log4j 2 and slf4j
+ -->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ <version>2.3</version>
+ </dependency>
+ <!--
+ 2/3 Required dependency for log4j 2 with slf4j: log4j 2 maven plugin (it is the log4j 2 implementation)
+ -->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>2.3</version>
+ </dependency>
+ <!--
+ 3/3 Required dependency for getting rid of commons logging.
+ This is the BRIDGE (no binding) between Jakarta Commons Logging (used by Spring) and whatever
+ I am using for logging (in this case I am using log4j 2)
+ See: http://www.slf4j.org/legacy.html
+
+ We need exclusions in every dependency using Jakarta Commons Logging (see Spring dependencies below)
+ -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>1.7.12</version>
+ </dependency>
+
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.3</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.7</version>
+ <configuration>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+package de.spring.example;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * This class is not using the AspectJ annotations, so we could use it on JDK 1.4 and below.
+ * If we want to use it as an Aspect we may JUST do it using a schema based declaration.
+ * What means, you can use this class as an Aspect JUST using an xml Spring declaration.
+ *
+ */
+public class GeneralAccess {
+ private static final Logger LOGGER = LoggerFactory.getLogger(GeneralAccess.class);
+
+
+ public void monitor()
+ {
+ LOGGER.info("I am the Advice monitor for TestB and I will be run before.");
+ }
+}
--- /dev/null
+package de.spring.example;
+
+import java.lang.reflect.Method;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.aop.MethodBeforeAdvice;
+
+/**
+ *
+ * We are using here an Advice of Spring 1.2
+ * See: http://static.springsource.org/spring/docs/3.1.0.RC1/spring-framework-reference/html/aop-api.html#aop-api-advice-types
+ *
+ */
+public class SpringAdvice implements MethodBeforeAdvice {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SpringAdvice.class);
+
+
+ public void before(Method m, Object[] args, Object target) throws Throwable {
+ LOGGER.info("I am the SpringAdvice and I will be run before.");
+ }
+
+}
--- /dev/null
+package de.spring.example;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+
+/**
+ *
+ */
+public final class SpringContextLocator {
+
+ // Singleton Pattern
+ private static SpringContextLocator instance;
+
+ // Spring ApplicationContext
+ private static ApplicationContext context;
+
+ // Spring Context
+ private static final String SPRING_CONFIG_CONTEXT="spring-config.xml";
+
+
+ /**
+ * Private constructor. Singleton pattern.
+ */
+ private SpringContextLocator() {
+ String[] factoryFiles = null;
+ System.out.println("Loading context files: " + SpringContextLocator.SPRING_CONFIG_CONTEXT);
+
+ factoryFiles = new String[] { SPRING_CONFIG_CONTEXT };
+
+ SpringContextLocator.context = new ClassPathXmlApplicationContext(factoryFiles);
+
+ System.out.println("The context has been loaded successfully!! ");
+ }
+
+ /**
+ * Singleton pattern not thread safety. To use SingletoHolder pattern as the best approximation
+ * otherwise to use an Enum class (see Effective Java Second Edition and ) if we need serialization.
+ */
+ public static SpringContextLocator getInstance() {
+ if (SpringContextLocator.instance == null) {
+ SpringContextLocator.instance = new SpringContextLocator();
+ }
+ return SpringContextLocator.instance;
+ }
+
+ /**
+ * Return bean from application context.
+ */
+ public Object getBean(final String name) {
+ return SpringContextLocator.context.getBean(name);
+ }
+}
\ No newline at end of file
--- /dev/null
+package de.spring.example;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import de.spring.example.service.TestB;
+import de.spring.example.web.TestA;
+
+public class SpringStart {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SpringStart.class);
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ LOGGER.info("Starting application");
+ SpringContextLocator.getInstance();
+
+ TestA testA = (TestA) SpringContextLocator.getInstance().getBean("testA");
+ testA.myMethod();
+
+ TestB testB = (TestB) SpringContextLocator.getInstance().getBean("testB");
+ testB.myMethod();
+ }
+}
--- /dev/null
+package de.spring.example;
+
+import org.aspectj.lang.annotation.Pointcut;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * Using the @Aspect annotation you could use this class as an Aspect without
+ * using a schema based declaration (without using <aop:aspect in the Spring xml file)
+ * What means, you could use this class as an Aspect without the xml Spring declaration.
+ *
+ */
+public class SystemArchitecture {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SystemArchitecture.class);
+
+
+ //Coonecting to the execution of any method defined in the
+ //package: de.spring.example.web
+ //We are connecting the methods defined in that package with this
+ //Pointcut. So, when executing any of those methods defined in that
+ //package we will run the Advice related to this Pointcut (if there is an Advice)
+ //NOTICE:
+ // WE ARE NOT USING THE @Aspect ANNOTATION, SO WE CAN USE THIS CLASS AS
+ // AN ASPECT AND THIS METHOD AS A POINTCUT JUST USING A SCHEMA BASED DECLARATION
+ @Pointcut("execution(* de.spring.example.web.*.*(..))")
+ public void pointCutMethod()
+ {
+ LOGGER.info("I am the Pointcut and you will never see me.");
+ //This is the PointCut.
+ //You can write code here, but it will be useless because while running
+ //the methods connected to the Pointcut, this code will not be executed.
+ //Just the advice will run!!!! :/
+ //Is not this weird? We are here defining a method whose code
+ //will never be run. When the hell should we write code here?
+ //This is a waste of time and code IMHO. Isn't it?
+ }
+
+ public void monitor()
+ {
+ LOGGER.info("I am the Advice monitor for TestA and I will be run before.");
+ }
+}
\ No newline at end of file
--- /dev/null
+package de.spring.example.service;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestB {
+ private static final Logger LOGGER = LoggerFactory.getLogger(TestB.class);
+
+ public int myMethod()
+ {
+ LOGGER.info("TestB: The Advice should be run before.");
+
+ //This value will be caught by the Advice with the @AfterReturning annotation.
+ return 999;
+ }
+}
--- /dev/null
+package de.spring.example.web;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestA {
+ private static final Logger LOGGER = LoggerFactory.getLogger(TestA.class);
+
+ public int myMethod()
+ {
+ LOGGER.info("TestA: The Advice should be run before.");
+
+ //This value will be caught by the Advice with the @AfterReturning annotation.
+ return 666;
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ status: The level of internal Log4j events that should be logged to the console.
+ Valid values for this attribute are "trace", "debug", "info", "warn", "error" and "fatal".
+
+ monitorInterval: The minimum amount of time, in seconds, that must elapse before the file configuration is checked for changes.
+
+
+ see https://logging.apache.org/log4j/2.x/manual/configuration.html
+ -->
+<Configuration status="error" strict="true" monitorInterval="30"
+ name="XMLConfigTest" packages="org.apache.logging.log4j.test">
+
+ <!--
+ ALL > TRACE > DEBUG > INFO > WARN > ERROR > OFF
+
+ ERROR by default.
+ -->
+
+ <Appenders>
+ <Appender type="Console" name="STDOUT">
+ <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
+ </Appender>
+ </Appenders>
+ <Loggers>
+
+ <!--
+ General logging Spring.
+ -->
+ <Logger name="org.springframework" level="INFO" additivity="false">
+ <AppenderRef ref="STDOUT" />
+ </Logger>
+
+
+ <!--
+ Anything else will be using TRACE logging level.
+ -->
+ <Root level="DEBUG">
+ <AppenderRef ref="STDOUT"/>
+ </Root>
+ </Loggers>
+</Configuration>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<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"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/aop
+ http://www.springframework.org/schema/aop/spring-aop.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/tx
+ http://www.springframework.org/schema/tx/spring-tx.xsd">
+
+ <!--
+ To force CGLIB proxying when using Spring AOP
+ See: http://static.springsource.org/spring/docs/3.1.0.RC1/spring-framework-reference/html/aop.html#aop-proxying
+ -->
+ <aop:config proxy-target-class="true">
+ <aop:aspect id="myAspectSchemaBased" ref="generalAccess">
+ <aop:pointcut id="aspectOperation"
+ expression="execution(* de.spring.example.service.*.*(..))"/>
+ <aop:before pointcut-ref="aspectOperation" method="monitor"/>
+ </aop:aspect>
+ </aop:config>
+
+
+ <aop:config proxy-target-class="true">
+ <aop:aspect id="myAspectwithAnnotations" ref="systemArchitecture">
+ <!--
+ See: http://static.springsource.org/spring/docs/3.1.0.RC1/spring-framework-reference/html/aop.html#aop-schema-pointcuts
+ "Note that the pointcut expression itself is using the same AspectJ pointcut expression
+ language as described in Section 8.2, “@AspectJ support”. If you are using the schema
+ based declaration style with Java 5, you can refer to named pointcuts defined in types
+ (@Aspects) within the pointcut expression, but this feature is not available on JDK 1.4 and below
+ (it relies on the Java 5 specific AspectJ reflection APIs). On JDK 1.5 therefore, another way of
+ defining the above pointcut would be:
+ -->
+ <aop:pointcut id="pointCutAspect"
+ expression="de.spring.example.SystemArchitecture.pointCutMethod()"/>
+ <!-- This will be the Advice. You can use the same class for it or you can use the aop:advisor
+ xml Spring annotation. In that case you have to use an Advice class from AOP support of Spring 1.2
+ (below you can see an example of this)
+ -->
+ <aop:before pointcut-ref="pointCutAspect" method="monitor"/>
+ </aop:aspect>
+ </aop:config>
+
+
+ <!--
+ We are using AOP support from Spring 1.2 :/ for this Advice
+ (we use Spring beans as advices and we can use the AOP support from Spring 1.2 for this)
+ We can use and mix whatever we want. Spring is powerful but at the same time it can be a complete mess.
+ -->
+ <aop:config proxy-target-class="true">
+ <aop:advisor pointcut="de.spring.example.SystemArchitecture.pointCutMethod()"
+ advice-ref="springAdvice" />
+ </aop:config>
+
+ <bean id="testA" class="de.spring.example.web.TestA">
+
+ </bean>
+
+ <bean id="testB" class="de.spring.example.service.TestB">
+
+ </bean>
+
+ <bean id="generalAccess" class="de.spring.example.GeneralAccess">
+
+ </bean>
+
+ <bean id="systemArchitecture" class="de.spring.example.SystemArchitecture">
+
+ </bean>
+
+ <bean id="springAdvice" class="de.spring.example.SpringAdvice">
+
+ </bean>
+
+</beans>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>de.spring.example</groupId>
+ <artifactId>spring-aspectj</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <name>spring-aspectj</name>
+ <url>http://gumartinm.name</url>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aspects</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aop</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>cglib</groupId>
+ <artifactId>cglib</artifactId>
+ <version>3.2.1</version>
+ </dependency>
+
+ <!--
+ 1/3 Required dependency for log4j 2 with slf4j: binding between log4j 2 and slf4j
+ -->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ <version>2.3</version>
+ </dependency>
+ <!--
+ 2/3 Required dependency for log4j 2 with slf4j: log4j 2 maven plugin (it is the log4j 2 implementation)
+ -->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>2.3</version>
+ </dependency>
+ <!--
+ 3/3 Required dependency for getting rid of commons logging.
+ This is the BRIDGE (no binding) between Jakarta Commons Logging (used by Spring) and whatever
+ I am using for logging (in this case I am using log4j 2)
+ See: http://www.slf4j.org/legacy.html
+
+ We need exclusions in every dependency using Jakarta Commons Logging (see Spring dependencies below)
+ -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>1.7.12</version>
+ </dependency>
+
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.3</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.7</version>
+ <configuration>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+package de.spring.example;
+
+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;
+
+@Aspect
+public class MyAdvice {
+ private static final Logger LOGGER = LoggerFactory.getLogger(MyAdvice.class);
+
+
+ //This advice is connected with the Pointcut defined in SystemArchitecture.
+ //So, every method connected to that Pointcut will be run after the
+ //method defined in this Advice.
+ @Before("de.spring.example.SystemArchitecture.pointCutMethod())")
+ public void doAccessCheck() {
+ LOGGER.info("I am the Advice and I will be run before.");
+ }
+
+
+ //NOTICE: YOU DO NOT NEED TO CREATE A SPECIAL CLASS FOR POINTCUTS
+ // YOU COULD DEFINE AN ADVICE WITHOUT A POINTCUT
+ //This advice has a PointCut defined like execution(* de.spring.example.web.Test.anotherExample())
+ //right here without a special PointCut method. This advice has itself the PointCut
+ @Around("execution(* de.spring.example.web.Test.anotherExample())")
+ public Object doAround(ProceedingJoinPoint pjp) {
+ LOGGER.info("I am the Advice and I will be run before and after. BEFORE");
+ // start stopwatch
+ // This local variable will store the returned value from the method anotherExample()
+ Object retVal=null;
+ try {
+ //Calling the real method
+ retVal = pjp.proceed();
+ } catch (Throwable e) {
+ LOGGER.info("Error", e);
+ }
+ // stop stopwatch
+ LOGGER.info("I am the Advice and I will be run before and after. AFTER " + retVal);
+ return retVal;
+ }
+}
--- /dev/null
+package de.spring.example;
+
+import java.lang.reflect.Method;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.aop.MethodBeforeAdvice;
+
+/**
+ *
+ * We are using here an Advice of Spring 1.2
+ * See: http://static.springsource.org/spring/docs/3.1.0.RC1/spring-framework-reference/html/aop-api.html#aop-api-advice-types
+ *
+ */
+public class SpringAdvice implements MethodBeforeAdvice {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SpringAdvice.class);
+
+ public void before(Method m, Object[] args, Object target) throws Throwable {
+ LOGGER.info("I am the SpringAdvice and I will be run before.");
+ }
+
+}
--- /dev/null
+package de.spring.example;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+
+/**
+ *
+ */
+public final class SpringContextLocator {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SpringAdvice.class);
+
+
+ // Singleton Pattern
+ private static SpringContextLocator instance;
+
+ // Spring ApplicationContext
+ private static ApplicationContext context;
+
+ // Spring Context
+ private static final String SPRING_CONFIG_CONTEXT="spring-config.xml";
+
+
+ /**
+ * Private constructor. Singleton pattern.
+ */
+ private SpringContextLocator() {
+ String[] factoryFiles = null;
+ LOGGER.info("Loading context files: " + SpringContextLocator.SPRING_CONFIG_CONTEXT);
+
+ factoryFiles = new String[] { SPRING_CONFIG_CONTEXT };
+
+ SpringContextLocator.context = new ClassPathXmlApplicationContext(factoryFiles);
+
+ LOGGER.info("The context has been loaded successfully!! ");
+ }
+
+ /**
+ * Singleton pattern not thread safety. To use SingletoHolder pattern as the best approximation
+ * otherwise to use an Enum class (see Effective Java Second Edition and ) if we need serialization.
+ */
+ public static SpringContextLocator getInstance() {
+ if (SpringContextLocator.instance == null) {
+ SpringContextLocator.instance = new SpringContextLocator();
+ }
+ return SpringContextLocator.instance;
+ }
+
+ /**
+ * Return bean from application context.
+ */
+ public Object getBean(final String name) {
+ return SpringContextLocator.context.getBean(name);
+ }
+}
\ No newline at end of file
--- /dev/null
+package de.spring.example;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import de.spring.example.web.Test;
+
+public class SpringStart {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SpringStart.class);
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ LOGGER.info("Starting application");
+ SpringContextLocator.getInstance();
+
+ Test test = (Test) SpringContextLocator.getInstance().getBean("test");
+ test.myMethod();
+ test.anotherExample();
+ }
+}
--- /dev/null
+package de.spring.example;
+
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * We are using here the @AspectJ annotations to declare
+ * Proxies. If we want to use these kinds of proxies on the Spring framework
+ * we have to use the <aop:aspectj-autoproxy/> annotation on the Spring xml file
+ * (the Spring context file)
+ */
+@Aspect
+public class SystemArchitecture {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SpringStart.class);
+
+
+ //Coonecting to the execution of any method defined in the
+ //package: de.spring.example.web
+ //We are connecting the methods defined in that package with this
+ //Pointcut. So, when executing any of those methods defined in that
+ //package we will run the Advice related to this Pointcut (if there is an Advice)
+ @Pointcut("execution(* de.spring.example.web.*.*(..))")
+ public void pointCutMethod()
+ {
+ LOGGER.info("I am the Pointcut and you will never see me.");
+ //This is the PointCut.
+ //You can write code here, but it will be useless because while running
+ //the methods connected to the Pointcut, this code will not be executed.
+ //Just the advice will run!!!! :/
+ //Is not this weird? We are here defining a method whose code
+ //will never be run. When the hell should we write code here?
+ //This is a waste of time and code IMHO. Isn't it?
+ }
+
+ //NOTICE: YOU DO NOT NEED TO CREATE A SPECIAL CLASS FOR THE ADVICE
+ // YOU COULD USE THE SAME CLASS FOR THE POINTCUTS AND FOR THE
+ // ADVICES. IN THIS CASE FOR EXAMPLE WE HAVE THE @AfterReturning
+ // ADVICE IN THIS CLASS AND THE @Before ADVICE IN THE CLASS CALLED
+ // MyAdvice
+ //This advice is connected with the another Pointcut.
+ //The returning value of every method connected to that Pointcut
+ //will be caught by this method.
+ @AfterReturning(pointcut="de.spring.example.SystemArchitecture.pointCutMethod())",
+ returning="retVal")
+ public void doAccessCheck(final Object retVal) {
+ LOGGER.info("The returned value by the method " +
+ "connected to the Pointcut: " + retVal);
+ }
+}
\ No newline at end of file
--- /dev/null
+package de.spring.example.web;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Test {
+ private static final Logger LOGGER = LoggerFactory.getLogger(Test.class);
+
+ public int myMethod()
+ {
+ LOGGER.info("The Advice should be run before.");
+
+ //This value will be caught by the Advice with the @AfterReturning annotation.
+ return 666;
+ }
+
+ public int anotherExample()
+ {
+ LOGGER.info("The Advice should be run before and after.");
+ return 666;
+
+ }
+
+ public class InnerTest {
+ public void innerMethod() {
+ LOGGER.info("I am the inner class. The Advice should be run after."
+ + " NO NEED OF DECLARING Spring BEANS WHEN WEAVING!!!!");
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ status: The level of internal Log4j events that should be logged to the console.
+ Valid values for this attribute are "trace", "debug", "info", "warn", "error" and "fatal".
+
+ monitorInterval: The minimum amount of time, in seconds, that must elapse before the file configuration is checked for changes.
+
+
+ see https://logging.apache.org/log4j/2.x/manual/configuration.html
+ -->
+<Configuration status="error" strict="true" monitorInterval="30"
+ name="XMLConfigTest" packages="org.apache.logging.log4j.test">
+
+ <!--
+ ALL > TRACE > DEBUG > INFO > WARN > ERROR > OFF
+
+ ERROR by default.
+ -->
+
+ <Appenders>
+ <Appender type="Console" name="STDOUT">
+ <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
+ </Appender>
+ </Appenders>
+ <Loggers>
+
+ <!--
+ General logging Spring.
+ -->
+ <Logger name="org.springframework" level="INFO" additivity="false">
+ <AppenderRef ref="STDOUT" />
+ </Logger>
+
+
+ <!--
+ Anything else will be using TRACE logging level.
+ -->
+ <Root level="DEBUG">
+ <AppenderRef ref="STDOUT"/>
+ </Root>
+ </Loggers>
+</Configuration>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<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"
+ xmlns:aop="http://www.springframework.org/schema/aop"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/aop
+ http://www.springframework.org/schema/aop/spring-aop.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/tx
+ http://www.springframework.org/schema/tx/spring-tx.xsd">
+
+ <!--
+ ************* WE HAVE TO ENABLE THE ASPECTJ SUPPORT!!!!!! *************
+ Otherwise the @Aspect annotation (defines @AspectJ aspects) will not work
+ It relies on the Java 5 specific AspectJ reflection APIs. You can not use it on
+ JDK 1.4 and below.
+
+
+ We could force here the use of CGLIB.
+ See: http://static.springsource.org/spring/docs/3.1.0.RC1/spring-framework-reference/html/aop.html#aop-proxying
+ Spring detects if the bean has an interface implementation. If it has one, Spring will use J2SE
+ (J2SE needs classes with interfaces) in other case it will use CGLIB.
+ In this example the "test" bean does not have an interface so Spring
+ will use CGLIB. We could force the use of CGLIB in classes with interfaces.
+ -->
+ <aop:aspectj-autoproxy/>
+
+ <!--
+ We can mix aspect types. Without this AOP declaration this project would be SPRING ASPECTJ
+ but, because of this, we have a Spring Advice declaration so this project will be a SPRING AOP project
+ (or at least it is not just SPRING ASPECTJ based)
+ Besides we are using AOP support used in Spring 1.2 :/
+ -->
+ <aop:config proxy-target-class="true">
+ <aop:advisor pointcut="de.spring.example.SystemArchitecture.pointCutMethod()"
+ advice-ref="springAdvice" />
+ </aop:config>
+
+
+ <bean id="test" class="de.spring.example.web.Test">
+
+ </bean>
+
+ <bean id="myAdvice" class="de.spring.example.MyAdvice">
+
+ </bean>
+
+ <bean id="systemArchitecture" class="de.spring.example.SystemArchitecture">
+
+ </bean>
+
+ <bean id="springAdvice" class="de.spring.example.SpringAdvice">
+
+ </bean>
+
+</beans>
--- /dev/null
+VM arguments:
+
+-javaagent:$HOME/.m2/repository/org/springframework/spring-instrument/4.2.5.RELEASE/spring-instrument-4.2.5.RELEASE.jar
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>de.spring.example</groupId>
+ <artifactId>spring-ltw</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <name>spring-ltw</name>
+ <url>http://gumartinm.name</url>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aspects</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aop</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-instrument</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>javax.cache</groupId>
+ <artifactId>cache-api</artifactId>
+ <version>1.0.0-PFD</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.transaction</groupId>
+ <artifactId>javax.transaction-api</artifactId>
+ <version>1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context-support</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-jdbc</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>cglib</groupId>
+ <artifactId>cglib</artifactId>
+ <version>3.2.1</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.mchange</groupId>
+ <artifactId>c3p0</artifactId>
+ <version>0.9.5.2</version>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>5.1.38</version>
+ </dependency>
+
+ <!--
+ 1/3 Required dependency for log4j 2 with slf4j: binding between log4j 2 and slf4j
+ -->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ <version>2.3</version>
+ </dependency>
+ <!--
+ 2/3 Required dependency for log4j 2 with slf4j: log4j 2 maven plugin (it is the log4j 2 implementation)
+ -->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>2.3</version>
+ </dependency>
+ <!--
+ 3/3 Required dependency for getting rid of commons logging.
+ This is the BRIDGE (no binding) between Jakarta Commons Logging (used by Spring) and whatever
+ I am using for logging (in this case I am using log4j 2)
+ See: http://www.slf4j.org/legacy.html
+
+ We need exclusions in every dependency using Jakarta Commons Logging (see Spring dependencies below)
+ -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>1.7.12</version>
+ </dependency>
+
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.3</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.7</version>
+ <configuration>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+package de.spring.example;
+
+import org.aspectj.lang.annotation.After;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Aspect
+public class MyAdvice {
+ private static final Logger LOGGER = LoggerFactory.getLogger(MyAdvice.class);
+
+ // With execution we avoid double weaving (when call and when execution)
+ @Before("@annotation(de.spring.example.annotation.initTransactional) && execution(* *(..))")
+ public void initTransactional()
+ {
+ LOGGER.info("I am the Advice initTransaction.");
+ TransactionManager.getInstance().initTransaction();
+ }
+
+
+ // With execution we avoid double weaving (when call and when execution)
+ @After("@annotation(de.spring.example.annotation.commitTransactional) && execution(* *(..))")
+ public void commitTransactional() {
+ LOGGER.info("I am the Advice commitTransaction.");
+ TransactionManager.getInstance().commitTransaction();
+ }
+}
--- /dev/null
+package de.spring.example;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+
+/**
+ *
+ */
+public final class SpringContextLocator {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SpringContextLocator.class);
+
+
+ // Singleton Pattern
+ private static SpringContextLocator instance;
+
+ // Spring ApplicationContext
+ private static ApplicationContext context;
+
+ // Spring Context
+ private static final String SPRING_CONFIG_CONTEXT="/spring-config.xml";
+
+
+ /**
+ * Private constructor. Singleton pattern.
+ */
+ private SpringContextLocator() {
+ String[] factoryFiles = null;
+ LOGGER.info("Loading context files: " + SpringContextLocator.SPRING_CONFIG_CONTEXT);
+
+ factoryFiles = new String[] { SPRING_CONFIG_CONTEXT };
+
+ SpringContextLocator.context = new ClassPathXmlApplicationContext(factoryFiles);
+
+ LOGGER.info("The context has been loaded successfully!! ");
+ }
+
+ /**
+ * Singleton pattern not thread safety. To use SingletoHolder pattern as the best approximation
+ * otherwise to use an Enum class (see Effective Java Second Edition and ) if we need serialization.
+ */
+ public static SpringContextLocator getInstance() {
+ if (SpringContextLocator.instance == null) {
+ SpringContextLocator.instance = new SpringContextLocator();
+ }
+ return SpringContextLocator.instance;
+ }
+
+ /**
+ * Return bean from application context.
+ */
+ public Object getBean(final String name) {
+ return SpringContextLocator.context.getBean(name);
+ }
+}
\ No newline at end of file
--- /dev/null
+package de.spring.example;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import de.spring.example.web.Test;
+
+public class SpringStart {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SpringStart.class);
+
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ LOGGER.info("Starting application");
+ SpringContextLocator.getInstance();
+
+ Test test = (Test) SpringContextLocator.getInstance().getBean("testOuter");
+ test.myMethod();
+ }
+}
--- /dev/null
+package de.spring.example;
+
+import org.aspectj.lang.annotation.Aspect;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.transaction.TransactionStatus;
+
+@Aspect
+public class TransactionManager {
+ private static final Logger LOGGER = LoggerFactory.getLogger(TransactionManager.class);
+ private static TransactionManager instance = new TransactionManager();
+ private DataSourceTransactionManager transactionManager;
+ private TransactionStatus transactionStatus;
+
+ //Why could you want to extend this class?
+ private TransactionManager() {
+ }
+
+ public static TransactionManager getInstance() {
+ return instance;
+ }
+
+ public void initTransaction()
+ {
+ LOGGER.info("initTRANSACTION");
+ // transactionStatus = this.transactionManager.getTransaction(null);
+ }
+
+ public void rollbackTransaction()
+ {
+ this.transactionManager.rollback(this.transactionStatus);
+ }
+
+
+ public void commitTransaction()
+ {
+ LOGGER.info("commitTRANSACTION");
+ // this.transactionManager.commit(this.transactionStatus);
+ }
+
+
+ /************************* Setters and getters *******************************************/
+ public void setTransactionManager(final DataSourceTransactionManager transactionManager)
+ {
+ this.transactionManager = transactionManager;
+ }
+}
--- /dev/null
+package de.spring.example.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.stereotype.Component;
+
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Component
+public @interface commitTransactional {
+}
--- /dev/null
+package de.spring.example.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.stereotype.Component;
+
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Component
+public @interface initTransactional {
+}
--- /dev/null
+package de.spring.example.web;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import de.spring.example.annotation.commitTransactional;
+import de.spring.example.annotation.initTransactional;
+
+
+public class Test {
+ private static final Logger LOGGER = LoggerFactory.getLogger(Test.class);
+
+ @initTransactional
+ public int myMethod()
+ {
+ LOGGER.info("The Advice should be run before.");
+
+ annotatedPrivateMethod();
+
+ InnerTest innerTest = new InnerTest();
+ innerTest.innerMethod();
+
+ return 666;
+ }
+
+ public class InnerTest {
+ @commitTransactional
+ public void innerMethod() {
+ LOGGER.info("I am the inner class. The Advice should be run after."
+ + " NO NEED OF DECLARING Spring BEANS WHEN WEAVING!!!!");
+ }
+ }
+
+ // IT WORKS WHEN WEAVING!!!
+ @initTransactional
+ private void annotatedPrivateMethod() {
+ LOGGER.info("The Advice should be run before even with private methods because I AM WEAVING."
+ + " IT WORKS EVEN CALLING FROM METHOD OF THE SAME CLASS. It doesn't when using proxies AOP.");
+ }
+}
--- /dev/null
+<!DOCTYPE aspectj PUBLIC
+ "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
+
+<aspectj>
+ <!--
+ With or without logs
+ <weaver>
+ -->
+ <weaver options="-verbose -showWeaveInfo">
+ <!-- only weave classes in our application-specific packages -->
+ <include within="de.spring..*"/>
+ <!--
+ Dump all types within the "somepack" package before they are woven
+ to the "./_ajdump" folder on disk
+ -->
+ <dump within="de.spring..*"/>
+ </weaver>
+
+ <aspects>
+ <aspect name="de.spring.example.MyAdvice"/>
+ </aspects>
+
+</aspectj>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ status: The level of internal Log4j events that should be logged to the console.
+ Valid values for this attribute are "trace", "debug", "info", "warn", "error" and "fatal".
+
+ monitorInterval: The minimum amount of time, in seconds, that must elapse before the file configuration is checked for changes.
+
+
+ see https://logging.apache.org/log4j/2.x/manual/configuration.html
+ -->
+<Configuration status="error" strict="true" monitorInterval="30"
+ name="XMLConfigTest" packages="org.apache.logging.log4j.test">
+
+ <!--
+ ALL > TRACE > DEBUG > INFO > WARN > ERROR > OFF
+
+ ERROR by default.
+ -->
+
+ <Appenders>
+ <Appender type="Console" name="STDOUT">
+ <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
+ </Appender>
+ </Appenders>
+ <Loggers>
+
+ <!--
+ General logging Spring.
+ -->
+ <Logger name="org.springframework" level="INFO" additivity="false">
+ <AppenderRef ref="STDOUT" />
+ </Logger>
+
+
+ <!--
+ Anything else will be using TRACE logging level.
+ -->
+ <Root level="DEBUG">
+ <AppenderRef ref="STDOUT"/>
+ </Root>
+ </Loggers>
+</Configuration>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<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">
+
+ <!--
+ We have to use SPRING ASPECTJ (no SPRING AOP 2.0/1.2) because we want to use
+ annotations with inner classes.
+ AspectJ under this configuration requires at least one 'META-INF/aop.xml' file
+ with the configuration about the Advices.
+
+ This switches on the load-time weaving
+ See: http://static.springsource.org/spring/docs/3.1.0.M2/spring-framework-reference/html/aop.html#aop-aj-ltw-spring
+ -->
+ <context:load-time-weaver weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"
+ aspectj-weaving="autodetect"/>
+
+
+ <bean id="myAdvice" class="de.spring.example.MyAdvice">
+
+ </bean>
+
+ <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
+ <property name="user" value="root"/>
+ <property name="password" value=""/>
+ <property name="driverClass" value="com.mysql.jdbc.Driver"/>
+ <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/example?autoReconnect=true"/>
+ <property name="initialPoolSize" value="5"/>
+ <property name="maxPoolSize" value="20"/>
+ <property name="minPoolSize" value="10"/>
+ <property name="acquireIncrement" value="1"/>
+ <property name="acquireRetryAttempts" value="5"/>
+ <property name="acquireRetryDelay" value="1000"/>
+ <property name="automaticTestTable" value="con_test"/>
+ <property name="checkoutTimeout" value="5000"/>
+ </bean>
+
+ <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
+ <property name="dataSource" ref="dataSource"/>
+ </bean>
+
+ <bean id="myTransactionManager"
+ class="de.spring.example.TransactionManager"
+ factory-method="getInstance">
+ <property name="transactionManager">
+ <ref bean="transactionManager" />
+ </property>
+ </bean>
+
+ <!--
+ In order to find annotations in inner classes we have to create Spring
+ beans of them. NO WHEN WEAVING!!! :)
+ -->
+ <bean id="testOuter" class="de.spring.example.web.Test"/>
+
+ <!--
+ WHEN WEAVING WE MAY ANNOTATE METHODS IN INNER CLASSES. SO, WE DO NOT NEED TO CREATE
+ Spring BEANS OF THEM. WITH PROXY AOP WE HAVE TO, BUT WHEN WEAVING NO!!!
+ <bean id="testInner" class="de.spring.example.web.Test$InnerTest">
+ <constructor-arg ref="testOuter"/>
+ </bean>
+ -->
+
+</beans>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>de.spring.example</groupId>
+ <artifactId>spring-maven-weaver</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <name>spring-maven-weaver</name>
+ <url>http://gumartinm.name</url>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aspects</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-aop</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.cache</groupId>
+ <artifactId>cache-api</artifactId>
+ <version>1.0.0-PFD</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.transaction</groupId>
+ <artifactId>javax.transaction-api</artifactId>
+ <version>1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context-support</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-jdbc</artifactId>
+ <version>4.2.5.RELEASE</version>
+ <!--
+ Required dependency for getting rid of commons logging and use my own logging library
+ (in my case I decided to use log4j 2 under slf4j)
+ -->
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <!-- Using aspectj-maven-plugin with AJDT -->
+ <dependency>
+ <groupId>org.aspectj</groupId>
+ <artifactId>aspectjrt</artifactId>
+ <version>1.8.9</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>cglib</groupId>
+ <artifactId>cglib</artifactId>
+ <version>3.2.1</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.mchange</groupId>
+ <artifactId>c3p0</artifactId>
+ <version>0.9.5.2</version>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>5.1.38</version>
+ </dependency>
+
+ <!--
+ 1/3 Required dependency for log4j 2 with slf4j: binding between log4j 2 and slf4j
+ -->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ <version>2.3</version>
+ </dependency>
+ <!--
+ 2/3 Required dependency for log4j 2 with slf4j: log4j 2 maven plugin (it is the log4j 2 implementation)
+ -->
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>2.3</version>
+ </dependency>
+ <!--
+ 3/3 Required dependency for getting rid of commons logging.
+ This is the BRIDGE (no binding) between Jakarta Commons Logging (used by Spring) and whatever
+ I am using for logging (in this case I am using log4j 2)
+ See: http://www.slf4j.org/legacy.html
+
+ We need exclusions in every dependency using Jakarta Commons Logging (see Spring dependencies below)
+ -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <version>1.7.12</version>
+ </dependency>
+
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.3</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ <executions>
+ <execution>
+ <!-- Modifying output directory of default compile because non-weaved
+ classes must be stored in separate folder to not confuse ajc by reweaving
+ already woven classes (which leads to to ajc error message like "bad weaverState.Kind:
+ -115") -->
+ <id>default-compile</id>
+ <configuration>
+ <compilerArguments>
+ <d>${project.build.directory}/unwoven-classes</d>
+ </compilerArguments>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.7</version>
+ <configuration>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>aspectj-maven-plugin</artifactId>
+ <version>1.8</version>
+ <configuration>
+ <ajdtBuildDefFile>build.ajproperties</ajdtBuildDefFile>
+ <weaveDirectories>
+ <weaveDirectory>${project.build.directory}/unwoven-classes</weaveDirectory>
+ </weaveDirectories>
+ <showWeaveInfo>true</showWeaveInfo>
+ <sources>
+ <source>
+ <basedir>src/main/java</basedir>
+ <includes>
+ <include>de.spring.example.MyAdvice.java</include>
+ </includes>
+ <excludes>
+ <exclude>**/logging/*.aj</exclude>
+ </excludes>
+ </source>
+ </sources>
+ </configuration>
+ <executions>
+ <execution>
+ <!-- Compile and weave aspects after all classes compiled by javac -->
+ <phase>process-classes</phase>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ </execution>
+ </executions>
+
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>aspectj-maven-plugin</artifactId>
+ <version>1.8</version>
+ <configuration>
+ <verbose>true</verbose>
+ <privateScope>true</privateScope>
+ <complianceLevel>1.5</complianceLevel>
+ <ajdtBuildDefFile>build.ajproperties</ajdtBuildDefFile>
+ </configuration>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>aspectj-report</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ </plugins>
+ </reporting>
+
+</project>
--- /dev/null
+package de.spring.example;
+
+import org.aspectj.lang.annotation.After;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Aspect
+public class MyAdvice {
+ private static final Logger LOGGER = LoggerFactory.getLogger(MyAdvice.class);
+
+ // With execution we avoid double weaving (when call and when execution)
+ @Before("@annotation(de.spring.example.annotation.initTransactional) && execution(* *(..))")
+ public void initTransactional()
+ {
+ LOGGER.info("I am the Advice initTransaction.");
+ TransactionManager.getInstance().initTransaction();
+ }
+
+
+ // With execution we avoid double weaving (when call and when execution)
+ @After("@annotation(de.spring.example.annotation.commitTransactional) && execution(* *(..))")
+ public void commitTransactional() {
+ LOGGER.info("I am the Advice commitTransaction.");
+ TransactionManager.getInstance().commitTransaction();
+ }
+}
--- /dev/null
+package de.spring.example;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+
+/**
+ *
+ */
+public final class SpringContextLocator {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SpringContextLocator.class);
+
+
+ // Singleton Pattern
+ private static SpringContextLocator instance;
+
+ // Spring ApplicationContext
+ private static ApplicationContext context;
+
+ // Spring Context
+ private static final String SPRING_CONFIG_CONTEXT="/spring-config.xml";
+
+
+ /**
+ * Private constructor. Singleton pattern.
+ */
+ private SpringContextLocator() {
+ String[] factoryFiles = null;
+ LOGGER.info("Loading context files: " + SpringContextLocator.SPRING_CONFIG_CONTEXT);
+
+ factoryFiles = new String[] { SPRING_CONFIG_CONTEXT };
+
+ SpringContextLocator.context = new ClassPathXmlApplicationContext(factoryFiles);
+
+ LOGGER.info("The context has been loaded successfully!! ");
+ }
+
+ /**
+ * Singleton pattern not thread safety. To use SingletoHolder pattern as the best approximation
+ * otherwise to use an Enum class (see Effective Java Second Edition and ) if we need serialization.
+ */
+ public static SpringContextLocator getInstance() {
+ if (SpringContextLocator.instance == null) {
+ SpringContextLocator.instance = new SpringContextLocator();
+ }
+ return SpringContextLocator.instance;
+ }
+
+ /**
+ * Return bean from application context.
+ */
+ public Object getBean(final String name) {
+ return SpringContextLocator.context.getBean(name);
+ }
+}
\ No newline at end of file
--- /dev/null
+package de.spring.example;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import de.spring.example.web.Test;
+
+public class SpringStart {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SpringStart.class);
+
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ LOGGER.info("Starting application");
+ SpringContextLocator.getInstance();
+
+ Test test = (Test) SpringContextLocator.getInstance().getBean("testOuter");
+ test.myMethod();
+ }
+}
--- /dev/null
+package de.spring.example;
+
+import org.aspectj.lang.annotation.Aspect;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.transaction.TransactionStatus;
+
+@Aspect
+public class TransactionManager {
+ private static final Logger LOGGER = LoggerFactory.getLogger(TransactionManager.class);
+ private static TransactionManager instance = new TransactionManager();
+ private DataSourceTransactionManager transactionManager;
+ private TransactionStatus transactionStatus;
+
+ //Why could you want to extend this class?
+ private TransactionManager() {
+ }
+
+ public static TransactionManager getInstance() {
+ return instance;
+ }
+
+ public void initTransaction()
+ {
+ LOGGER.info("initTRANSACTION");
+ // transactionStatus = this.transactionManager.getTransaction(null);
+ }
+
+ public void rollbackTransaction()
+ {
+ this.transactionManager.rollback(this.transactionStatus);
+ }
+
+
+ public void commitTransaction()
+ {
+ LOGGER.info("commitTRANSACTION");
+ // this.transactionManager.commit(this.transactionStatus);
+ }
+
+
+ /************************* Setters and getters *******************************************/
+ public void setTransactionManager(final DataSourceTransactionManager transactionManager)
+ {
+ this.transactionManager = transactionManager;
+ }
+}
--- /dev/null
+package de.spring.example.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.stereotype.Component;
+
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Component
+public @interface commitTransactional {
+}
--- /dev/null
+package de.spring.example.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.stereotype.Component;
+
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Component
+public @interface initTransactional {
+}
--- /dev/null
+package de.spring.example.web;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import de.spring.example.annotation.commitTransactional;
+import de.spring.example.annotation.initTransactional;
+
+
+public class Test {
+ private static final Logger LOGGER = LoggerFactory.getLogger(Test.class);
+
+ @initTransactional
+ public int myMethod()
+ {
+ LOGGER.info("The Advice should be run before.");
+
+ annotatedPrivateMethod();
+
+ InnerTest innerTest = new InnerTest();
+ innerTest.innerMethod();
+
+ return 666;
+ }
+
+ public class InnerTest {
+ @commitTransactional
+ public void innerMethod() {
+ LOGGER.info("I am the inner class. The Advice should be run after."
+ + " NO NEED OF DECLARING Spring BEANS WHEN WEAVING!!!!");
+ }
+ }
+
+ // IT WORKS WHEN WEAVING!!!
+ @initTransactional
+ private void annotatedPrivateMethod() {
+ LOGGER.info("The Advice should be run before even with private methods because I AM WEAVING."
+ + " IT WORKS EVEN CALLING FROM METHOD OF THE SAME CLASS. It doesn't when using proxies AOP.");
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ status: The level of internal Log4j events that should be logged to the console.
+ Valid values for this attribute are "trace", "debug", "info", "warn", "error" and "fatal".
+
+ monitorInterval: The minimum amount of time, in seconds, that must elapse before the file configuration is checked for changes.
+
+
+ see https://logging.apache.org/log4j/2.x/manual/configuration.html
+ -->
+<Configuration status="error" strict="true" monitorInterval="30"
+ name="XMLConfigTest" packages="org.apache.logging.log4j.test">
+
+ <!--
+ ALL > TRACE > DEBUG > INFO > WARN > ERROR > OFF
+
+ ERROR by default.
+ -->
+
+ <Appenders>
+ <Appender type="Console" name="STDOUT">
+ <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
+ </Appender>
+ </Appenders>
+ <Loggers>
+
+ <!--
+ General logging Spring.
+ -->
+ <Logger name="org.springframework" level="INFO" additivity="false">
+ <AppenderRef ref="STDOUT" />
+ </Logger>
+
+
+ <!--
+ Anything else will be using TRACE logging level.
+ -->
+ <Root level="DEBUG">
+ <AppenderRef ref="STDOUT"/>
+ </Root>
+ </Loggers>
+</Configuration>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<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">
+
+ <!--
+ We have to use SPRING ASPECTJ (no SPRING AOP 2.0/1.2) because we want to use
+ annotations with inner classes.
+ AspectJ under this configuration requires at least one 'META-INF/aop.xml' file
+ with the configuration about the Advices.
+
+ This switches on the load-time weaving
+ See: http://static.springsource.org/spring/docs/3.1.0.M2/spring-framework-reference/html/aop.html#aop-aj-ltw-spring
+ -->
+ <context:load-time-weaver weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"
+ aspectj-weaving="autodetect"/>
+
+
+ <bean id="myAdvice" class="de.spring.example.MyAdvice">
+
+ </bean>
+
+ <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
+ <property name="user" value="root"/>
+ <property name="password" value=""/>
+ <property name="driverClass" value="com.mysql.jdbc.Driver"/>
+ <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/example?autoReconnect=true"/>
+ <property name="initialPoolSize" value="5"/>
+ <property name="maxPoolSize" value="20"/>
+ <property name="minPoolSize" value="10"/>
+ <property name="acquireIncrement" value="1"/>
+ <property name="acquireRetryAttempts" value="5"/>
+ <property name="acquireRetryDelay" value="1000"/>
+ <property name="automaticTestTable" value="con_test"/>
+ <property name="checkoutTimeout" value="5000"/>
+ </bean>
+
+ <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
+ <property name="dataSource" ref="dataSource"/>
+ </bean>
+
+ <bean id="myTransactionManager"
+ class="de.spring.example.TransactionManager"
+ factory-method="getInstance">
+ <property name="transactionManager">
+ <ref bean="transactionManager" />
+ </property>
+ </bean>
+
+ <!--
+ In order to find annotations in inner classes we have to create Spring
+ beans of them. NO WHEN WEAVING!!! :)
+ -->
+ <bean id="testOuter" class="de.spring.example.web.Test"/>
+
+ <!--
+ WHEN WEAVING WE MAY ANNOTATE METHODS IN INNER CLASSES. SO, WE DO NOT NEED TO CREATE
+ Spring BEANS OF THEM. WITH PROXY AOP WE HAVE TO, BUT WHEN WEAVING NO!!!
+ <bean id="testInner" class="de.spring.example.web.Test$InnerTest">
+ <constructor-arg ref="testOuter"/>
+ </bean>
+ -->
+
+</beans>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<project
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
- xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-
- <modelVersion>4.0.0</modelVersion>
- <groupId>de.spring.example</groupId>
- <artifactId>spring-aop-example</artifactId>
- <version>2.0-SNAPSHOT</version>
- <name>spring-aop-example</name>
- <url>http://gumartinm.name</url>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>4.2.5.RELEASE</version>
- <!--
- Required dependency for getting rid of commons logging and use my own logging library
- (in my case I decided to use log4j 2 under slf4j)
- -->
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aspects</artifactId>
- <version>4.2.5.RELEASE</version>
- <!--
- Required dependency for getting rid of commons logging and use my own logging library
- (in my case I decided to use log4j 2 under slf4j)
- -->
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aop</artifactId>
- <version>4.2.5.RELEASE</version>
- <!--
- Required dependency for getting rid of commons logging and use my own logging library
- (in my case I decided to use log4j 2 under slf4j)
- -->
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>cglib</groupId>
- <artifactId>cglib</artifactId>
- <version>3.2.1</version>
- </dependency>
-
- <!--
- 1/3 Required dependency for log4j 2 with slf4j: binding between log4j 2 and slf4j
- -->
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-slf4j-impl</artifactId>
- <version>2.3</version>
- </dependency>
- <!--
- 2/3 Required dependency for log4j 2 with slf4j: log4j 2 maven plugin (it is the log4j 2 implementation)
- -->
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-core</artifactId>
- <version>2.3</version>
- </dependency>
- <!--
- 3/3 Required dependency for getting rid of commons logging.
- This is the BRIDGE (no binding) between Jakarta Commons Logging (used by Spring) and whatever
- I am using for logging (in this case I am using log4j 2)
- See: http://www.slf4j.org/legacy.html
-
- We need exclusions in every dependency using Jakarta Commons Logging (see Spring dependencies below)
- -->
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- <version>1.7.12</version>
- </dependency>
-
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.3</version>
- <configuration>
- <source>1.8</source>
- <target>1.8</target>
- <encoding>${project.build.sourceEncoding}</encoding>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-resources-plugin</artifactId>
- <version>2.7</version>
- <configuration>
- <encoding>${project.build.sourceEncoding}</encoding>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-package de.spring.example;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- * This class is not using the AspectJ annotations, so we could use it on JDK 1.4 and below.
- * If we want to use it as an Aspect we may JUST do it using a schema based declaration.
- * What means, you can use this class as an Aspect JUST using an xml Spring declaration.
- *
- */
-public class GeneralAccess {
- private static final Logger LOGGER = LoggerFactory.getLogger(GeneralAccess.class);
-
-
- public void monitor()
- {
- LOGGER.info("I am the Advice monitor for TestB and I will be run before.");
- }
-}
+++ /dev/null
-package de.spring.example;
-
-import java.lang.reflect.Method;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.aop.MethodBeforeAdvice;
-
-/**
- *
- * We are using here an Advice of Spring 1.2
- * See: http://static.springsource.org/spring/docs/3.1.0.RC1/spring-framework-reference/html/aop-api.html#aop-api-advice-types
- *
- */
-public class SpringAdvice implements MethodBeforeAdvice {
- private static final Logger LOGGER = LoggerFactory.getLogger(SpringAdvice.class);
-
-
- public void before(Method m, Object[] args, Object target) throws Throwable {
- LOGGER.info("I am the SpringAdvice and I will be run before.");
- }
-
-}
+++ /dev/null
-package de.spring.example;
-
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-
-
-/**
- *
- */
-public final class SpringContextLocator {
-
- // Singleton Pattern
- private static SpringContextLocator instance;
-
- // Spring ApplicationContext
- private static ApplicationContext context;
-
- // Spring Context
- private static final String SPRING_CONFIG_CONTEXT="spring-config.xml";
-
-
- /**
- * Private constructor. Singleton pattern.
- */
- private SpringContextLocator() {
- String[] factoryFiles = null;
- System.out.println("Loading context files: " + SpringContextLocator.SPRING_CONFIG_CONTEXT);
-
- factoryFiles = new String[] { SPRING_CONFIG_CONTEXT };
-
- SpringContextLocator.context = new ClassPathXmlApplicationContext(factoryFiles);
-
- System.out.println("The context has been loaded successfully!! ");
- }
-
- /**
- * Singleton pattern not thread safety. To use SingletoHolder pattern as the best approximation
- * otherwise to use an Enum class (see Effective Java Second Edition and ) if we need serialization.
- */
- public static SpringContextLocator getInstance() {
- if (SpringContextLocator.instance == null) {
- SpringContextLocator.instance = new SpringContextLocator();
- }
- return SpringContextLocator.instance;
- }
-
- /**
- * Return bean from application context.
- */
- public Object getBean(final String name) {
- return SpringContextLocator.context.getBean(name);
- }
-}
\ No newline at end of file
+++ /dev/null
-package de.spring.example;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import de.spring.example.service.TestB;
-import de.spring.example.web.TestA;
-
-public class SpringStart {
- private static final Logger LOGGER = LoggerFactory.getLogger(SpringStart.class);
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- LOGGER.info("Starting application");
- SpringContextLocator.getInstance();
-
- TestA testA = (TestA) SpringContextLocator.getInstance().getBean("testA");
- testA.myMethod();
-
- TestB testB = (TestB) SpringContextLocator.getInstance().getBean("testB");
- testB.myMethod();
- }
-}
+++ /dev/null
-package de.spring.example;
-
-import org.aspectj.lang.annotation.Pointcut;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- * Using the @Aspect annotation you could use this class as an Aspect without
- * using a schema based declaration (without using <aop:aspect in the Spring xml file)
- * What means, you could use this class as an Aspect without the xml Spring declaration.
- *
- */
-public class SystemArchitecture {
- private static final Logger LOGGER = LoggerFactory.getLogger(SystemArchitecture.class);
-
-
- //Coonecting to the execution of any method defined in the
- //package: de.spring.example.web
- //We are connecting the methods defined in that package with this
- //Pointcut. So, when executing any of those methods defined in that
- //package we will run the Advice related to this Pointcut (if there is an Advice)
- //NOTICE:
- // WE ARE NOT USING THE @Aspect ANNOTATION, SO WE CAN USE THIS CLASS AS
- // AN ASPECT AND THIS METHOD AS A POINTCUT JUST USING A SCHEMA BASED DECLARATION
- @Pointcut("execution(* de.spring.example.web.*.*(..))")
- public void pointCutMethod()
- {
- LOGGER.info("I am the Pointcut and you will never see me.");
- //This is the PointCut.
- //You can write code here, but it will be useless because while running
- //the methods connected to the Pointcut, this code will not be executed.
- //Just the advice will run!!!! :/
- //Is not this weird? We are here defining a method whose code
- //will never be run. When the hell should we write code here?
- //This is a waste of time and code IMHO. Isn't it?
- }
-
- public void monitor()
- {
- LOGGER.info("I am the Advice monitor for TestA and I will be run before.");
- }
-}
\ No newline at end of file
+++ /dev/null
-package de.spring.example.service;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TestB {
- private static final Logger LOGGER = LoggerFactory.getLogger(TestB.class);
-
- public int myMethod()
- {
- LOGGER.info("TestB: The Advice should be run before.");
-
- //This value will be caught by the Advice with the @AfterReturning annotation.
- return 999;
- }
-}
+++ /dev/null
-package de.spring.example.web;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TestA {
- private static final Logger LOGGER = LoggerFactory.getLogger(TestA.class);
-
- public int myMethod()
- {
- LOGGER.info("TestA: The Advice should be run before.");
-
- //This value will be caught by the Advice with the @AfterReturning annotation.
- return 666;
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- status: The level of internal Log4j events that should be logged to the console.
- Valid values for this attribute are "trace", "debug", "info", "warn", "error" and "fatal".
-
- monitorInterval: The minimum amount of time, in seconds, that must elapse before the file configuration is checked for changes.
-
-
- see https://logging.apache.org/log4j/2.x/manual/configuration.html
- -->
-<Configuration status="error" strict="true" monitorInterval="30"
- name="XMLConfigTest" packages="org.apache.logging.log4j.test">
-
- <!--
- ALL > TRACE > DEBUG > INFO > WARN > ERROR > OFF
-
- ERROR by default.
- -->
-
- <Appenders>
- <Appender type="Console" name="STDOUT">
- <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
- </Appender>
- </Appenders>
- <Loggers>
-
- <!--
- General logging Spring.
- -->
- <Logger name="org.springframework" level="INFO" additivity="false">
- <AppenderRef ref="STDOUT" />
- </Logger>
-
-
- <!--
- Anything else will be using TRACE logging level.
- -->
- <Root level="DEBUG">
- <AppenderRef ref="STDOUT"/>
- </Root>
- </Loggers>
-</Configuration>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<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"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/aop
- http://www.springframework.org/schema/aop/spring-aop.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context.xsd
- http://www.springframework.org/schema/tx
- http://www.springframework.org/schema/tx/spring-tx.xsd">
-
- <!--
- To force CGLIB proxying when using Spring AOP
- See: http://static.springsource.org/spring/docs/3.1.0.RC1/spring-framework-reference/html/aop.html#aop-proxying
- -->
- <aop:config proxy-target-class="true">
- <aop:aspect id="myAspectSchemaBased" ref="generalAccess">
- <aop:pointcut id="aspectOperation"
- expression="execution(* de.spring.example.service.*.*(..))"/>
- <aop:before pointcut-ref="aspectOperation" method="monitor"/>
- </aop:aspect>
- </aop:config>
-
-
- <aop:config proxy-target-class="true">
- <aop:aspect id="myAspectwithAnnotations" ref="systemArchitecture">
- <!--
- See: http://static.springsource.org/spring/docs/3.1.0.RC1/spring-framework-reference/html/aop.html#aop-schema-pointcuts
- "Note that the pointcut expression itself is using the same AspectJ pointcut expression
- language as described in Section 8.2, “@AspectJ support”. If you are using the schema
- based declaration style with Java 5, you can refer to named pointcuts defined in types
- (@Aspects) within the pointcut expression, but this feature is not available on JDK 1.4 and below
- (it relies on the Java 5 specific AspectJ reflection APIs). On JDK 1.5 therefore, another way of
- defining the above pointcut would be:
- -->
- <aop:pointcut id="pointCutAspect"
- expression="de.spring.example.SystemArchitecture.pointCutMethod()"/>
- <!-- This will be the Advice. You can use the same class for it or you can use the aop:advisor
- xml Spring annotation. In that case you have to use an Advice class from AOP support of Spring 1.2
- (below you can see an example of this)
- -->
- <aop:before pointcut-ref="pointCutAspect" method="monitor"/>
- </aop:aspect>
- </aop:config>
-
-
- <!--
- We are using AOP support from Spring 1.2 :/ for this Advice
- (we use Spring beans as advices and we can use the AOP support from Spring 1.2 for this)
- We can use and mix whatever we want. Spring is powerful but at the same time it can be a complete mess.
- -->
- <aop:config proxy-target-class="true">
- <aop:advisor pointcut="de.spring.example.SystemArchitecture.pointCutMethod()"
- advice-ref="springAdvice" />
- </aop:config>
-
- <bean id="testA" class="de.spring.example.web.TestA">
-
- </bean>
-
- <bean id="testB" class="de.spring.example.service.TestB">
-
- </bean>
-
- <bean id="generalAccess" class="de.spring.example.GeneralAccess">
-
- </bean>
-
- <bean id="systemArchitecture" class="de.spring.example.SystemArchitecture">
-
- </bean>
-
- <bean id="springAdvice" class="de.spring.example.SpringAdvice">
-
- </bean>
-
-</beans>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<project
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
- xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-
- <modelVersion>4.0.0</modelVersion>
- <groupId>de.spring.example</groupId>
- <artifactId>spring-aspectj</artifactId>
- <version>2.0-SNAPSHOT</version>
- <name>spring-aspectj</name>
- <url>http://gumartinm.name</url>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>4.2.5.RELEASE</version>
- <!--
- Required dependency for getting rid of commons logging and use my own logging library
- (in my case I decided to use log4j 2 under slf4j)
- -->
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aspects</artifactId>
- <version>4.2.5.RELEASE</version>
- <!--
- Required dependency for getting rid of commons logging and use my own logging library
- (in my case I decided to use log4j 2 under slf4j)
- -->
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aop</artifactId>
- <version>4.2.5.RELEASE</version>
- <!--
- Required dependency for getting rid of commons logging and use my own logging library
- (in my case I decided to use log4j 2 under slf4j)
- -->
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>cglib</groupId>
- <artifactId>cglib</artifactId>
- <version>3.2.1</version>
- </dependency>
-
- <!--
- 1/3 Required dependency for log4j 2 with slf4j: binding between log4j 2 and slf4j
- -->
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-slf4j-impl</artifactId>
- <version>2.3</version>
- </dependency>
- <!--
- 2/3 Required dependency for log4j 2 with slf4j: log4j 2 maven plugin (it is the log4j 2 implementation)
- -->
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-core</artifactId>
- <version>2.3</version>
- </dependency>
- <!--
- 3/3 Required dependency for getting rid of commons logging.
- This is the BRIDGE (no binding) between Jakarta Commons Logging (used by Spring) and whatever
- I am using for logging (in this case I am using log4j 2)
- See: http://www.slf4j.org/legacy.html
-
- We need exclusions in every dependency using Jakarta Commons Logging (see Spring dependencies below)
- -->
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- <version>1.7.12</version>
- </dependency>
-
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.3</version>
- <configuration>
- <source>1.8</source>
- <target>1.8</target>
- <encoding>${project.build.sourceEncoding}</encoding>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-resources-plugin</artifactId>
- <version>2.7</version>
- <configuration>
- <encoding>${project.build.sourceEncoding}</encoding>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-package de.spring.example;
-
-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;
-
-@Aspect
-public class MyAdvice {
- private static final Logger LOGGER = LoggerFactory.getLogger(MyAdvice.class);
-
-
- //This advice is connected with the Pointcut defined in SystemArchitecture.
- //So, every method connected to that Pointcut will be run after the
- //method defined in this Advice.
- @Before("de.spring.example.SystemArchitecture.pointCutMethod())")
- public void doAccessCheck() {
- LOGGER.info("I am the Advice and I will be run before.");
- }
-
-
- //NOTICE: YOU DO NOT NEED TO CREATE A SPECIAL CLASS FOR POINTCUTS
- // YOU COULD DEFINE AN ADVICE WITHOUT A POINTCUT
- //This advice has a PointCut defined like execution(* de.spring.example.web.Test.anotherExample())
- //right here without a special PointCut method. This advice has itself the PointCut
- @Around("execution(* de.spring.example.web.Test.anotherExample())")
- public Object doAround(ProceedingJoinPoint pjp) {
- LOGGER.info("I am the Advice and I will be run before and after. BEFORE");
- // start stopwatch
- // This local variable will store the returned value from the method anotherExample()
- Object retVal=null;
- try {
- //Calling the real method
- retVal = pjp.proceed();
- } catch (Throwable e) {
- LOGGER.info("Error", e);
- }
- // stop stopwatch
- LOGGER.info("I am the Advice and I will be run before and after. AFTER " + retVal);
- return retVal;
- }
-}
+++ /dev/null
-package de.spring.example;
-
-import java.lang.reflect.Method;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.aop.MethodBeforeAdvice;
-
-/**
- *
- * We are using here an Advice of Spring 1.2
- * See: http://static.springsource.org/spring/docs/3.1.0.RC1/spring-framework-reference/html/aop-api.html#aop-api-advice-types
- *
- */
-public class SpringAdvice implements MethodBeforeAdvice {
- private static final Logger LOGGER = LoggerFactory.getLogger(SpringAdvice.class);
-
- public void before(Method m, Object[] args, Object target) throws Throwable {
- LOGGER.info("I am the SpringAdvice and I will be run before.");
- }
-
-}
+++ /dev/null
-package de.spring.example;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-
-
-/**
- *
- */
-public final class SpringContextLocator {
- private static final Logger LOGGER = LoggerFactory.getLogger(SpringAdvice.class);
-
-
- // Singleton Pattern
- private static SpringContextLocator instance;
-
- // Spring ApplicationContext
- private static ApplicationContext context;
-
- // Spring Context
- private static final String SPRING_CONFIG_CONTEXT="spring-config.xml";
-
-
- /**
- * Private constructor. Singleton pattern.
- */
- private SpringContextLocator() {
- String[] factoryFiles = null;
- LOGGER.info("Loading context files: " + SpringContextLocator.SPRING_CONFIG_CONTEXT);
-
- factoryFiles = new String[] { SPRING_CONFIG_CONTEXT };
-
- SpringContextLocator.context = new ClassPathXmlApplicationContext(factoryFiles);
-
- LOGGER.info("The context has been loaded successfully!! ");
- }
-
- /**
- * Singleton pattern not thread safety. To use SingletoHolder pattern as the best approximation
- * otherwise to use an Enum class (see Effective Java Second Edition and ) if we need serialization.
- */
- public static SpringContextLocator getInstance() {
- if (SpringContextLocator.instance == null) {
- SpringContextLocator.instance = new SpringContextLocator();
- }
- return SpringContextLocator.instance;
- }
-
- /**
- * Return bean from application context.
- */
- public Object getBean(final String name) {
- return SpringContextLocator.context.getBean(name);
- }
-}
\ No newline at end of file
+++ /dev/null
-package de.spring.example;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import de.spring.example.web.Test;
-
-public class SpringStart {
- private static final Logger LOGGER = LoggerFactory.getLogger(SpringStart.class);
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- LOGGER.info("Starting application");
- SpringContextLocator.getInstance();
-
- Test test = (Test) SpringContextLocator.getInstance().getBean("test");
- test.myMethod();
- test.anotherExample();
- }
-}
+++ /dev/null
-package de.spring.example;
-
-import org.aspectj.lang.annotation.AfterReturning;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- * We are using here the @AspectJ annotations to declare
- * Proxies. If we want to use these kinds of proxies on the Spring framework
- * we have to use the <aop:aspectj-autoproxy/> annotation on the Spring xml file
- * (the Spring context file)
- */
-@Aspect
-public class SystemArchitecture {
- private static final Logger LOGGER = LoggerFactory.getLogger(SpringStart.class);
-
-
- //Coonecting to the execution of any method defined in the
- //package: de.spring.example.web
- //We are connecting the methods defined in that package with this
- //Pointcut. So, when executing any of those methods defined in that
- //package we will run the Advice related to this Pointcut (if there is an Advice)
- @Pointcut("execution(* de.spring.example.web.*.*(..))")
- public void pointCutMethod()
- {
- LOGGER.info("I am the Pointcut and you will never see me.");
- //This is the PointCut.
- //You can write code here, but it will be useless because while running
- //the methods connected to the Pointcut, this code will not be executed.
- //Just the advice will run!!!! :/
- //Is not this weird? We are here defining a method whose code
- //will never be run. When the hell should we write code here?
- //This is a waste of time and code IMHO. Isn't it?
- }
-
- //NOTICE: YOU DO NOT NEED TO CREATE A SPECIAL CLASS FOR THE ADVICE
- // YOU COULD USE THE SAME CLASS FOR THE POINTCUTS AND FOR THE
- // ADVICES. IN THIS CASE FOR EXAMPLE WE HAVE THE @AfterReturning
- // ADVICE IN THIS CLASS AND THE @Before ADVICE IN THE CLASS CALLED
- // MyAdvice
- //This advice is connected with the another Pointcut.
- //The returning value of every method connected to that Pointcut
- //will be caught by this method.
- @AfterReturning(pointcut="de.spring.example.SystemArchitecture.pointCutMethod())",
- returning="retVal")
- public void doAccessCheck(final Object retVal) {
- LOGGER.info("The returned value by the method " +
- "connected to the Pointcut: " + retVal);
- }
-}
\ No newline at end of file
+++ /dev/null
-package de.spring.example.web;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class Test {
- private static final Logger LOGGER = LoggerFactory.getLogger(Test.class);
-
- public int myMethod()
- {
- LOGGER.info("The Advice should be run before.");
-
- //This value will be caught by the Advice with the @AfterReturning annotation.
- return 666;
- }
-
- public int anotherExample()
- {
- LOGGER.info("The Advice should be run before and after.");
- return 666;
-
- }
-
- public class InnerTest {
- public void innerMethod() {
- LOGGER.info("I am the inner class. The Advice should be run after."
- + " NO NEED OF DECLARING Spring BEANS WHEN WEAVING!!!!");
- }
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- status: The level of internal Log4j events that should be logged to the console.
- Valid values for this attribute are "trace", "debug", "info", "warn", "error" and "fatal".
-
- monitorInterval: The minimum amount of time, in seconds, that must elapse before the file configuration is checked for changes.
-
-
- see https://logging.apache.org/log4j/2.x/manual/configuration.html
- -->
-<Configuration status="error" strict="true" monitorInterval="30"
- name="XMLConfigTest" packages="org.apache.logging.log4j.test">
-
- <!--
- ALL > TRACE > DEBUG > INFO > WARN > ERROR > OFF
-
- ERROR by default.
- -->
-
- <Appenders>
- <Appender type="Console" name="STDOUT">
- <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
- </Appender>
- </Appenders>
- <Loggers>
-
- <!--
- General logging Spring.
- -->
- <Logger name="org.springframework" level="INFO" additivity="false">
- <AppenderRef ref="STDOUT" />
- </Logger>
-
-
- <!--
- Anything else will be using TRACE logging level.
- -->
- <Root level="DEBUG">
- <AppenderRef ref="STDOUT"/>
- </Root>
- </Loggers>
-</Configuration>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<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"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/aop
- http://www.springframework.org/schema/aop/spring-aop.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context.xsd
- http://www.springframework.org/schema/tx
- http://www.springframework.org/schema/tx/spring-tx.xsd">
-
- <!--
- ************* WE HAVE TO ENABLE THE ASPECTJ SUPPORT!!!!!! *************
- Otherwise the @Aspect annotation (defines @AspectJ aspects) will not work
- It relies on the Java 5 specific AspectJ reflection APIs. You can not use it on
- JDK 1.4 and below.
-
-
- We could force here the use of CGLIB.
- See: http://static.springsource.org/spring/docs/3.1.0.RC1/spring-framework-reference/html/aop.html#aop-proxying
- Spring detects if the bean has an interface implementation. If it has one, Spring will use J2SE
- (J2SE needs classes with interfaces) in other case it will use CGLIB.
- In this example the "test" bean does not have an interface so Spring
- will use CGLIB. We could force the use of CGLIB in classes with interfaces.
- -->
- <aop:aspectj-autoproxy/>
-
- <!--
- We can mix aspect types. Without this AOP declaration this project would be SPRING ASPECTJ
- but, because of this, we have a Spring Advice declaration so this project will be a SPRING AOP project
- (or at least it is not just SPRING ASPECTJ based)
- Besides we are using AOP support used in Spring 1.2 :/
- -->
- <aop:config proxy-target-class="true">
- <aop:advisor pointcut="de.spring.example.SystemArchitecture.pointCutMethod()"
- advice-ref="springAdvice" />
- </aop:config>
-
-
- <bean id="test" class="de.spring.example.web.Test">
-
- </bean>
-
- <bean id="myAdvice" class="de.spring.example.MyAdvice">
-
- </bean>
-
- <bean id="systemArchitecture" class="de.spring.example.SystemArchitecture">
-
- </bean>
-
- <bean id="springAdvice" class="de.spring.example.SpringAdvice">
-
- </bean>
-
-</beans>
+++ /dev/null
-VM arguments:
-
--javaagent:$HOME/.m2/repository/org/springframework/spring-instrument/4.2.5.RELEASE/spring-instrument-4.2.5.RELEASE.jar
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<project
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
- xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-
- <modelVersion>4.0.0</modelVersion>
- <groupId>de.spring.example</groupId>
- <artifactId>spring-ltw</artifactId>
- <version>2.0-SNAPSHOT</version>
- <name>spring-ltw</name>
- <url>http://gumartinm.name</url>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>4.2.5.RELEASE</version>
- <!--
- Required dependency for getting rid of commons logging and use my own logging library
- (in my case I decided to use log4j 2 under slf4j)
- -->
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aspects</artifactId>
- <version>4.2.5.RELEASE</version>
- <!--
- Required dependency for getting rid of commons logging and use my own logging library
- (in my case I decided to use log4j 2 under slf4j)
- -->
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aop</artifactId>
- <version>4.2.5.RELEASE</version>
- <!--
- Required dependency for getting rid of commons logging and use my own logging library
- (in my case I decided to use log4j 2 under slf4j)
- -->
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-instrument</artifactId>
- <version>4.2.5.RELEASE</version>
- <!--
- Required dependency for getting rid of commons logging and use my own logging library
- (in my case I decided to use log4j 2 under slf4j)
- -->
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>javax.cache</groupId>
- <artifactId>cache-api</artifactId>
- <version>1.0.0-PFD</version>
- </dependency>
- <dependency>
- <groupId>javax.transaction</groupId>
- <artifactId>javax.transaction-api</artifactId>
- <version>1.2</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context-support</artifactId>
- <version>4.2.5.RELEASE</version>
- <!--
- Required dependency for getting rid of commons logging and use my own logging library
- (in my case I decided to use log4j 2 under slf4j)
- -->
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>4.2.5.RELEASE</version>
- <!--
- Required dependency for getting rid of commons logging and use my own logging library
- (in my case I decided to use log4j 2 under slf4j)
- -->
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>cglib</groupId>
- <artifactId>cglib</artifactId>
- <version>3.2.1</version>
- </dependency>
-
- <dependency>
- <groupId>com.mchange</groupId>
- <artifactId>c3p0</artifactId>
- <version>0.9.5.2</version>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>5.1.38</version>
- </dependency>
-
- <!--
- 1/3 Required dependency for log4j 2 with slf4j: binding between log4j 2 and slf4j
- -->
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-slf4j-impl</artifactId>
- <version>2.3</version>
- </dependency>
- <!--
- 2/3 Required dependency for log4j 2 with slf4j: log4j 2 maven plugin (it is the log4j 2 implementation)
- -->
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-core</artifactId>
- <version>2.3</version>
- </dependency>
- <!--
- 3/3 Required dependency for getting rid of commons logging.
- This is the BRIDGE (no binding) between Jakarta Commons Logging (used by Spring) and whatever
- I am using for logging (in this case I am using log4j 2)
- See: http://www.slf4j.org/legacy.html
-
- We need exclusions in every dependency using Jakarta Commons Logging (see Spring dependencies below)
- -->
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- <version>1.7.12</version>
- </dependency>
-
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.3</version>
- <configuration>
- <source>1.8</source>
- <target>1.8</target>
- <encoding>${project.build.sourceEncoding}</encoding>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-resources-plugin</artifactId>
- <version>2.7</version>
- <configuration>
- <encoding>${project.build.sourceEncoding}</encoding>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-package de.spring.example;
-
-import org.aspectj.lang.annotation.After;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Before;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Aspect
-public class MyAdvice {
- private static final Logger LOGGER = LoggerFactory.getLogger(MyAdvice.class);
-
- // With execution we avoid double weaving (when call and when execution)
- @Before("@annotation(de.spring.example.annotation.initTransactional) && execution(* *(..))")
- public void initTransactional()
- {
- LOGGER.info("I am the Advice initTransaction.");
- TransactionManager.getInstance().initTransaction();
- }
-
-
- // With execution we avoid double weaving (when call and when execution)
- @After("@annotation(de.spring.example.annotation.commitTransactional) && execution(* *(..))")
- public void commitTransactional() {
- LOGGER.info("I am the Advice commitTransaction.");
- TransactionManager.getInstance().commitTransaction();
- }
-}
+++ /dev/null
-package de.spring.example;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-
-
-/**
- *
- */
-public final class SpringContextLocator {
- private static final Logger LOGGER = LoggerFactory.getLogger(SpringContextLocator.class);
-
-
- // Singleton Pattern
- private static SpringContextLocator instance;
-
- // Spring ApplicationContext
- private static ApplicationContext context;
-
- // Spring Context
- private static final String SPRING_CONFIG_CONTEXT="/spring-config.xml";
-
-
- /**
- * Private constructor. Singleton pattern.
- */
- private SpringContextLocator() {
- String[] factoryFiles = null;
- LOGGER.info("Loading context files: " + SpringContextLocator.SPRING_CONFIG_CONTEXT);
-
- factoryFiles = new String[] { SPRING_CONFIG_CONTEXT };
-
- SpringContextLocator.context = new ClassPathXmlApplicationContext(factoryFiles);
-
- LOGGER.info("The context has been loaded successfully!! ");
- }
-
- /**
- * Singleton pattern not thread safety. To use SingletoHolder pattern as the best approximation
- * otherwise to use an Enum class (see Effective Java Second Edition and ) if we need serialization.
- */
- public static SpringContextLocator getInstance() {
- if (SpringContextLocator.instance == null) {
- SpringContextLocator.instance = new SpringContextLocator();
- }
- return SpringContextLocator.instance;
- }
-
- /**
- * Return bean from application context.
- */
- public Object getBean(final String name) {
- return SpringContextLocator.context.getBean(name);
- }
-}
\ No newline at end of file
+++ /dev/null
-package de.spring.example;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import de.spring.example.web.Test;
-
-public class SpringStart {
- private static final Logger LOGGER = LoggerFactory.getLogger(SpringStart.class);
-
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- LOGGER.info("Starting application");
- SpringContextLocator.getInstance();
-
- Test test = (Test) SpringContextLocator.getInstance().getBean("testOuter");
- test.myMethod();
- }
-}
+++ /dev/null
-package de.spring.example;
-
-import org.aspectj.lang.annotation.Aspect;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.jdbc.datasource.DataSourceTransactionManager;
-import org.springframework.transaction.TransactionStatus;
-
-@Aspect
-public class TransactionManager {
- private static final Logger LOGGER = LoggerFactory.getLogger(TransactionManager.class);
- private static TransactionManager instance = new TransactionManager();
- private DataSourceTransactionManager transactionManager;
- private TransactionStatus transactionStatus;
-
- //Why could you want to extend this class?
- private TransactionManager() {
- }
-
- public static TransactionManager getInstance() {
- return instance;
- }
-
- public void initTransaction()
- {
- LOGGER.info("initTRANSACTION");
- // transactionStatus = this.transactionManager.getTransaction(null);
- }
-
- public void rollbackTransaction()
- {
- this.transactionManager.rollback(this.transactionStatus);
- }
-
-
- public void commitTransaction()
- {
- LOGGER.info("commitTRANSACTION");
- // this.transactionManager.commit(this.transactionStatus);
- }
-
-
- /************************* Setters and getters *******************************************/
- public void setTransactionManager(final DataSourceTransactionManager transactionManager)
- {
- this.transactionManager = transactionManager;
- }
-}
+++ /dev/null
-package de.spring.example.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import org.springframework.stereotype.Component;
-
-@Target({ElementType.METHOD, ElementType.TYPE})
-@Retention(RetentionPolicy.RUNTIME)
-@Component
-public @interface commitTransactional {
-}
+++ /dev/null
-package de.spring.example.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import org.springframework.stereotype.Component;
-
-@Target({ElementType.METHOD, ElementType.TYPE})
-@Retention(RetentionPolicy.RUNTIME)
-@Component
-public @interface initTransactional {
-}
+++ /dev/null
-package de.spring.example.web;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import de.spring.example.annotation.commitTransactional;
-import de.spring.example.annotation.initTransactional;
-
-
-public class Test {
- private static final Logger LOGGER = LoggerFactory.getLogger(Test.class);
-
- @initTransactional
- public int myMethod()
- {
- LOGGER.info("The Advice should be run before.");
-
- annotatedPrivateMethod();
-
- InnerTest innerTest = new InnerTest();
- innerTest.innerMethod();
-
- return 666;
- }
-
- public class InnerTest {
- @commitTransactional
- public void innerMethod() {
- LOGGER.info("I am the inner class. The Advice should be run after."
- + " NO NEED OF DECLARING Spring BEANS WHEN WEAVING!!!!");
- }
- }
-
- // IT WORKS WHEN WEAVING!!!
- @initTransactional
- private void annotatedPrivateMethod() {
- LOGGER.info("The Advice should be run before even with private methods because I AM WEAVING."
- + " IT WORKS EVEN CALLING FROM METHOD OF THE SAME CLASS. It doesn't when using proxies AOP.");
- }
-}
+++ /dev/null
-<!DOCTYPE aspectj PUBLIC
- "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
-
-<aspectj>
- <!--
- With or without logs
- <weaver>
- -->
- <weaver options="-verbose -showWeaveInfo">
- <!-- only weave classes in our application-specific packages -->
- <include within="de.spring..*"/>
- <!--
- Dump all types within the "somepack" package before they are woven
- to the "./_ajdump" folder on disk
- -->
- <dump within="de.spring..*"/>
- </weaver>
-
- <aspects>
- <aspect name="de.spring.example.MyAdvice"/>
- </aspects>
-
-</aspectj>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- status: The level of internal Log4j events that should be logged to the console.
- Valid values for this attribute are "trace", "debug", "info", "warn", "error" and "fatal".
-
- monitorInterval: The minimum amount of time, in seconds, that must elapse before the file configuration is checked for changes.
-
-
- see https://logging.apache.org/log4j/2.x/manual/configuration.html
- -->
-<Configuration status="error" strict="true" monitorInterval="30"
- name="XMLConfigTest" packages="org.apache.logging.log4j.test">
-
- <!--
- ALL > TRACE > DEBUG > INFO > WARN > ERROR > OFF
-
- ERROR by default.
- -->
-
- <Appenders>
- <Appender type="Console" name="STDOUT">
- <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
- </Appender>
- </Appenders>
- <Loggers>
-
- <!--
- General logging Spring.
- -->
- <Logger name="org.springframework" level="INFO" additivity="false">
- <AppenderRef ref="STDOUT" />
- </Logger>
-
-
- <!--
- Anything else will be using TRACE logging level.
- -->
- <Root level="DEBUG">
- <AppenderRef ref="STDOUT"/>
- </Root>
- </Loggers>
-</Configuration>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<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">
-
- <!--
- We have to use SPRING ASPECTJ (no SPRING AOP 2.0/1.2) because we want to use
- annotations with inner classes.
- AspectJ under this configuration requires at least one 'META-INF/aop.xml' file
- with the configuration about the Advices.
-
- This switches on the load-time weaving
- See: http://static.springsource.org/spring/docs/3.1.0.M2/spring-framework-reference/html/aop.html#aop-aj-ltw-spring
- -->
- <context:load-time-weaver weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"
- aspectj-weaving="autodetect"/>
-
-
- <bean id="myAdvice" class="de.spring.example.MyAdvice">
-
- </bean>
-
- <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
- <property name="user" value="root"/>
- <property name="password" value=""/>
- <property name="driverClass" value="com.mysql.jdbc.Driver"/>
- <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/example?autoReconnect=true"/>
- <property name="initialPoolSize" value="5"/>
- <property name="maxPoolSize" value="20"/>
- <property name="minPoolSize" value="10"/>
- <property name="acquireIncrement" value="1"/>
- <property name="acquireRetryAttempts" value="5"/>
- <property name="acquireRetryDelay" value="1000"/>
- <property name="automaticTestTable" value="con_test"/>
- <property name="checkoutTimeout" value="5000"/>
- </bean>
-
- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="dataSource"/>
- </bean>
-
- <bean id="myTransactionManager"
- class="de.spring.example.TransactionManager"
- factory-method="getInstance">
- <property name="transactionManager">
- <ref bean="transactionManager" />
- </property>
- </bean>
-
- <!--
- In order to find annotations in inner classes we have to create Spring
- beans of them. NO WHEN WEAVING!!! :)
- -->
- <bean id="testOuter" class="de.spring.example.web.Test"/>
-
- <!--
- WHEN WEAVING WE MAY ANNOTATE METHODS IN INNER CLASSES. SO, WE DO NOT NEED TO CREATE
- Spring BEANS OF THEM. WITH PROXY AOP WE HAVE TO, BUT WHEN WEAVING NO!!!
- <bean id="testInner" class="de.spring.example.web.Test$InnerTest">
- <constructor-arg ref="testOuter"/>
- </bean>
- -->
-
-</beans>