Posted on 2006-04-23 15:17
oxl 阅读(1142)
评论(0) 编辑 收藏 所属分类:
J2EE 设计模式与应用
这一周我都在用空余的时间来看Spring这个东西,突然觉得这个东西并没有想像中那么深不可测,最多只有AOP这方面的东西不是我所熟悉的,不过经过自己努力,也不是不可理解的。
AOP,面向切面的编程,是一种从各个方面对软件系统进行关注的开发方法,也就是说,可以把要实现的系统从多个方面进行理解和开发。比如一个系统,它包含了业务逻辑,日志管理,安全管理(认证管理)等,一般而言,我在开发包含这些方面的程序时,就很容易进入单面一维的操作去:比如下面是一个用户管理程序的部份:
1、验证用户是否已经登录
2、记录日志
3、进行操作,对重要的操作都可能要进行日志记录。
4、记录用户离开时间
......
由上面的步骤可以看到,真正的业务逻辑只有第3步,其它的都是附加的功能,或者是从另一方面加入的功能,他们和业务逻辑是相辅相成,可是业务逻辑并不需要知道这些附加的功能,又从另一方面来看,每一进行的操作都会触发附加的操作,而且这些应该是自动的,业务逻辑所不知道的。
所以就引进一个拦截器的概念,对用户的操作进行拦截,然后进行附加的操作。而用户的操作并不知道这些拦截器的存在,从而可以使开发业务逻辑的程序员可以专心地写他的业务逻辑,而其它程序员则专心写他的拦截器,从而就可以使程序员从多个方面进行关注,进行编程。而Spring AOP就起到了这个拦截器的作用,而这些就演化出很多的术语,也无非是拦截器而已,现在俗一点来理解这些个术语:
切面:宏观上要关注的编程方面,比如安全管理方面,日志记录方面,而这些都只是宏观上的,没有任何代码实现,就好像这样说:我这个系统要一个安全管理系统等等,就是大至上需要这个切面功能。
通知(Advice):切面功能的代码实现,也就是说具体的切面功能。
连接点(Joinpoint):程序运行中可以把通知道插入的所有地方,比如某方法前,后,或抛出异常,而所以这些方法的插入点都是连接点。
切入点(Pointcut):定义了通知可以插入到哪些连接点。
Advisor:这里只有Spring才有,它包含了通知和切入点,以定义在什么连接点插入什么通知。
下面我用一个代码例子来说明:
文件:SayHelloService.java
1 package
com.bullonline.study.spring.ch03;
2
3 public interface
SayHelloService {
4 public void
printMessage(String message);
5 public void
printInfomation(String info);
6
}
7
文件:SayHelloServiceImpl.java
1 package
com.bullonline.study.spring.ch03;
2
3 public class SayHelloServiceImpl implements
SayHelloService {
4
5 public void
printMessage(String message) {
6 System.out.println("message:" +
message);
7 System.out.println("---------------------------------\n"
);
8
}
9
10 public void
printInfomation(String info) {
11 System.out.println("..Infomation"
);
12 System.out.println("= love is good ="
);
13
System.out.println(info);
14 System.out.println("---------------------------------\n"
);
15
}
16
17
}
18
文件:SayHelloAdvice.java
1 package
com.bullonline.study.spring.ch03;
2
3 import
java.lang.reflect.Method;
4
5 import
org.springframework.aop.MethodBeforeAdvice;
6
7 public class SayHelloAdvice implements
MethodBeforeAdvice {
8
9 public void
before(Method method, Object[] args, Object target)
10 throws
Throwable {
11 System.out.println(method.toString() + ": say hello to you!!"
);
12
}
13
14 }
文件:MyClassFilter.java
1 package
com.bullonline.study.spring.ch03;
2
3 import
org.springframework.aop.ClassFilter;
4
5 public class MyClassFilter implements
ClassFilter {
6
7 public boolean
matches(Class target) {
8 return true
;
9
}
10
11
}
12
文件:MyMethodMatcher.java
1 package
com.bullonline.study.spring.ch03;
2
3 import
java.lang.reflect.Method;
4
5 import
org.springframework.aop.MethodMatcher;
6
7 public class MyMethodMatcher implements
MethodMatcher {
8
9 public boolean
matches(Method method, Class target) {
10 String methodName =
method.getName();
11 if (methodName.equals("printMessage"
)) {
12 return true
;
13 } else
{
14 return false
;
15
}
16
}
17
18 public boolean
isRuntime() {
19 return false
;
20
}
21
22 public boolean
matches(Method arg0, Class arg1, Object[] arg2) {
23 return false
;
24
}
25
26
}
27
文件:MyPointcut.java
1 package com.bullonline.study.spring.ch03;
2
3 import org.springframework.aop.ClassFilter;
4 import org.springframework.aop.MethodMatcher;
5 import org.springframework.aop.Pointcut;
6
7 public class MyPointcut implements Pointcut {
8 private ClassFilter filter;
9 private MethodMatcher matcher;
10
11 public void setClassFilter(ClassFilter filter) {
12 this.filter = filter;
13 }
14
15 public void setMethodMatcher(MethodMatcher matcher) {
16 this.matcher = matcher;
17 }
18
19 public ClassFilter getClassFilter() {
20 return this.filter;
21 }
22
23 public MethodMatcher getMethodMatcher() {
24 return this.matcher;
25 }
26
27 }
28
文件:MyPointcutAdvisor.java
1 package com.bullonline.study.spring.ch03;
2
3 import org.aopalliance.aop.Advice;
4 import org.springframework.aop.Pointcut;
5 import org.springframework.aop.PointcutAdvisor;
6
7 public class MyPointcutAdvisor implements PointcutAdvisor {
8 private Pointcut pointcut;
9 private Advice advice;
10
11 public void setPointcut(Pointcut pointcut) {
12 this.pointcut = pointcut;
13 }
14
15 public void setAdvice(Advice advice) {
16 this.advice = advice;
17 }
18
19 public Pointcut getPointcut() {
20 return this.pointcut;
21 }
22
23 public boolean isPerInstance() {
24 return false;
25 }
26
27 public Advice getAdvice() {
28 return this.advice;
29 }
30
31 }
32
文件:TestApp.java
1 package com.bullonline.study.spring.ch03;
2
3 import org.springframework.beans.factory.BeanFactory;
4 import org.springframework.beans.factory.xml.XmlBeanFactory;
5 import org.springframework.core.io.ClassPathResource;
6
7 public class TestApp {
8 public static void main(String[] args) {
9 BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
10 SayHelloService service = (SayHelloService) factory.getBean("sayHelloService");
11 service.printMessage("Hello, World!!");
12 service.printInfomation("haha..");
13
14 }
15
16 }
17
文件:applicationContext.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
3
4 <beans>
5 <bean id="helloWorld" class="com.bullonline.study.spring.ch01.HelloWorld">
6 <property name="message" value="Haha.Hello, World!!"></property>
7 </bean>
8
9 <bean id="sayHelloServiceImpl" class="com.bullonline.study.spring.ch03.SayHelloServiceImpl" />
10 <bean id="classFilter" class="com.bullonline.study.spring.ch03.MyClassFilter" />
11 <bean id="methodMatcher" class="com.bullonline.study.spring.ch03.MyMethodMatcher" />
12 <bean id="sayHelloAdvice" class="com.bullonline.study.spring.ch03.SayHelloAdvice" />
13
14 <bean id="myPointcut" class="com.bullonline.study.spring.ch03.MyPointcut">
15 <property name="classFilter">
16 <ref bean="classFilter"/>
17 </property>
18 <property name="methodMatcher">
19 <ref bean="methodMatcher"/>
20 </property>
21 </bean>
22
23 <bean id="myPointcutAdvisor" class="com.bullonline.study.spring.ch03.MyPointcutAdvisor">
24 <property name="pointcut">
25 <ref bean="myPointcut"/>
26 </property>
27 <property name="advice">
28 <ref bean="sayHelloAdvice"/>
29 </property>
30 </bean>
31
32 <bean id="sayHelloService" class="org.springframework.aop.framework.ProxyFactoryBean">
33 <property name="proxyInterfaces">
34 <value>com.bullonline.study.spring.ch03.SayHelloService</value>
35 </property>
36 <property name="interceptorNames">
37 <list>
38 <value>myPointcutAdvisor</value>
39 </list>
40 </property>
41 <property name="target">
42 <ref bean="sayHelloServiceImpl" />
43 </property>
44 </bean>
45 </beans>
46