研究了2天的AOP,终于有点眉目了,AOP的那么多概念弄的头也大了,看了很多文章真是不知所云。弄清楚了其实很简单,那些名字都是忽悠。
简单而言:通过OOP已经设计了一些类和方法,我们希望能够在这些类的实例执行相应的方法的时候去执行另外一个类中的一些方法。执行哪些代码和已经通过OOP设计的类和方法无关。而是直接通过配置就能做到的。
看看DEMO:
- 一。有一个如下接口
package com.hzjc.test;
public interface Component {
void business1();//商业逻辑方法1
void business2();//商业逻辑方法2
void business3();//商业逻辑方法3
}
一个实现:
package com.hzjc.test.impl;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import com.hzjc.test.Component;
public class ComponentImpl implements Component {
public void business1() {
// TODO Auto-generated method stub
System.out.println("执行业务处理方法1");
}
public void business2() {
// TODO Auto-generated method stub
System.out.println("执行业务处理方法2");
}
public void business3() {
// TODO Auto-generated method stub
System.out.println("执行业务处理方法3");
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext context =
new org.springframework.context.support.ClassPathXmlApplicationContext("beans.xml");
Component component=(Component)context.getBean("component");
// Resource resource = new FileSystemResource("beans.xml");
// BeanFactory factory = new XmlBeanFactory(resource);
// Component component=(Component)factory.getBean("component");
component.business1();
System.out.println("-----------");
component.business2();
}
}
还有一个BEAN配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="component"
class="springroad.demo.chap5.exampleB.ComponentImpl">
</bean>
</beans>
这个是SPRING的IOC的知识,通过SPRING得到一个实例并且运行。
二。我们来加入AOP,简单讲就是想让Component 的实例执行business1等的方法的时候去做一些事情。
比如在执行business1的时候,做用户验证等。
看下面这个类:
public class AspectBean {
public void validateUser()
{
System.out.println("执行用户验证!");
}
public void writeLogInfo()
{
System.out.println("书写日志信息");
}
public void beginTransaction()
{
System.out.println("开始事务");
}
public void endTransaction()
{
System.out.println("结束事务");
}
}
我们希望这些这个类中的这些方法。
Spring2实现AOP有两种方式:
1.基于Schema的配置文件配置Spring AOP
2.使用Java5注解配置及使用Spring AOP
也就是说一种是通过XML配置的,一种是通过注解的。
先看看通过配置的方法。
bean.XML配置如下
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:config>
<!--只是取了个名字,然后关联上那个要执行的类—>
<aop:aspect id="aspectDemo" ref="aspectBean">
<!--定义了业务类执行所有包含business名字的方法的时候要做点事情,(但是什么时候执行和执行什么事情?需要在后面定义)-->
<aop:pointcut id="somePointcut"
expression="execution(* springroad.demo.chap5.exampleB.Component.business*(..))" />
<aop:before pointcut-ref="somePointcut"
method="validateUser" />
<aop:before pointcut-ref="somePointcut"
method="beginTransaction" />
<aop:after-returning pointcut-ref="somePointcut"
method="endTransaction" />
<aop:after-returning pointcut-ref="somePointcut"
method="writeLogInfo" />
</aop:aspect>
</aop:config>
<bean id="aspectBean"
class="springroad.demo.chap5.exampleB.AspectBean">
</bean>
<bean id="component"
class="springroad.demo.chap5.exampleB.ComponentImpl">
</bean>
</beans>
注意点:
1.需要增加命名空间。
2.增加一个AOP的配置。配置是什么意识呢?看注解就OK了。
---------------------------------------------------------------------------------------
再来看看通过Java5注解配置的方法:
其实要告诉给SPRING的东西是一样的,就是要告诉SPRING,什么类在执行什么方法的时候去干什么事情。
这个时候那个要被执行的类就要有所变化了。
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;
@Aspect //定义说我这个类比较特别,是用来被其他类执行时触发用的
public class AspectAnnotationBean {
//定义说springroad.demo.chap5.exampleB.Component类在执行所有包含business名字的方法时,要做事情。
@Pointcut("execution(* springroad.demo.chap5.exampleB.Component.business*(..))")
public void somePointcut()
{
}
//要执行前面定义的哪些类的方法之前执行validateUser方法。
@Before("somePointcut()")
public void validateUser()
{
System.out.println("执行用户验证!");
}
@After("somePointcut()")
public void writeLogInfo()
{
System.out.println("书写日志信息");
}
@Before("somePointcut()")
public void beginTransaction()
{
System.out.println("开始事务");
}
@After("somePointcut()")
public void endTransaction()
{
System.out.println("结束事务");
}
}
OK,这个特殊的类写好了,然后还是需要设置一下XML.
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<aop:aspectj-autoproxy />
<bean id="aspectBean"
class="springroad.demo.chap5.exampleB.AspectAnnotationBean">
</bean>
<bean id="component"
class="springroad.demo.chap5.exampleB.ComponentImpl">
</bean>
</beans>
当然这个XML就简单多了,因为需要告诉SPRING的东西都在那个特殊的类里告诉过了。但是要注意2点:
1.还是命名空间和前面一样的。
2.<aop:aspectj-autoproxy />,加了这个才会有效果
--------------------------------------------------------------------------------
整个例子就这样了,偶是网上下了一个
《深入Spring 2:轻量级J2EE开发框架原理与实践》第五章
面向切面的编程(AOP)及在Spring中的应用
这个书看到的。哪下的也忘记了。呵呵。