AOP 面向切面,可以让我们在不修改业务代码的前提下,在业务代码执行前后进行执行相应的模块,这样,我们就可以把诸如日志的功能模块合核心业务模块分隔开来,以往的的日志做法都是由核心模块主动的调用日志记录功能,耦合性很强,使用AOP技术,可以将日志模块作为切面,插入到核心业务前执行,核心业务并不主动的调用日志记录功能
本例中使用GreetingHelloworldImpl代表核心业务模块,使用LoggerService代表作为aop实现的日志模块
核心业务并没有主动依赖日志模块
package SimpleAOPTest;

public interface GreetingHelloworld ......{
public void sayHelloworld();
}

package SimpleAOPTest;

public class GreetingHelloworldImpl implements GreetingHelloworld ......{
private String greetingText;
private String greetingFromConstructor;
public GreetingHelloworldImpl(String greetingFromConstructor)......{
this.greetingFromConstructor=greetingFromConstructor;
}
public GreetingHelloworldImpl()......{
}
public String getGreetingText() ......{
return greetingText;
}
public void setGreetingText(String greetingText) ......{
this.greetingText = greetingText;
}
public void sayHelloworld() ......{
System.out.println(this.getGreetingText());
System.out.println(this.getGreetingFromConstructor());
}
public String getGreetingFromConstructor() ......{
return greetingFromConstructor;
}
public void setGreetingFromConstructor(String greetingFromConstructor) ......{
this.greetingFromConstructor = greetingFromConstructor;
}
}
package SimpleAOPTest;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;

public class LoggerService implements MethodBeforeAdvice ......{
public LoggerService()......{
}
public void before(Method method, Object[] obj, Object target)
throws Throwable ......{
System.out.println("this is info from LoggerService");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>
<bean id="greetingTarget" class="SimpleAOPTest.GreetingHelloworldImpl">
<constructor-arg>
<value>this is helloworld from construtor</value>
</constructor-arg>
<property name="greetingText">
<value>hello world!</value>
</property>
</bean>
<bean id="loggerService" class="SimpleAOPTest.LoggerService"></bean>
<bean id="greeting" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>SimpleAOPTest.GreetingHelloworld</value> <!-- 拦截GreetingHelloworld接口中的方法 -->
</list>
</property>
<property name="interceptorNames">
<list>
<value>loggerService</value> <!-- 处理loggerService请求,切入 -->
</list>
</property>
<property name="target">
<ref bean="greetingTarget"/> <!-- 然后处理greeting请求 -->
</property>
<!-- 代理目标为类时设置
<property name="proxyTargetClass">
<value>true</value>
</property>
-->
</bean>
</beans>
package SimpleAOPTest;
import java.io.File;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

public class TestHelloWorld ......{

public static void main(String[] args) ......{
String filePath=System.getProperty("user.dir")+File.separator+"SimpleAOPTest"+File.separator+"hello.xml";
BeanFactory factory=new XmlBeanFactory(new FileSystemResource(filePath));
//代理目标为接口时使用
GreetingHelloworld greetingSerview=(GreetingHelloworld)factory.getBean("greeting");
//代理目标为类是使用,并配置xml中proxyTargetClass,需要CGLIB包
//<property name="proxyTargetClass">
//<value>true</value>
//</property>
//GreetingHelloworldImpl greetingSerview=(GreetingHelloworldImpl)factory.getBean("greeting");
greetingSerview.sayHelloworld();
}
// public static String getRealPath(String filename){
// String path="";
// Class theClass=TestHelloWorld.class;
// java.net.URL u= theClass.getResource(filename);
// return u.getPath();
//
//
// }
}
2007-5-14 23:13:47 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from file [E:/项目/SpringInActionStudy/SimpleAOPTest/hello.xml]
this is info from LoggerService
hello world!
this is helloworld from construtor
可以看到,日志模块打印的信息“this is info from LoggerService”在核心业务运行之前执行了,这样,我们就算对日至模块进行天翻地覆的变化,都不会影响我们的核心业务
本文介绍了一种利用AOP技术实现日志模块的方法,通过示例代码展示了如何在业务逻辑执行前后插入日志记录,有效降低了核心业务与日志功能之间的耦合度。
155

被折叠的 条评论
为什么被折叠?



