用ProxyFactoryBean代理的面向切面编程

(1)以下是LogRegiste类,它是一个通知(Advise)。该类实现了MethodInterceptor接口,实现该接口需要实现一个invoke()方法,在invoke()方法中必须要调用proceed()方法,如果忘记这样做,就会导致通知被使用了,但目标方法却没有被执行。利用周围通知可以检查和修改被通知方法的返回值,让我们可以在把方法的返回值传递给调用者之前对其进行一些处理。AfterReturningAdvice只能对返回值进行检查,但不能修改它。
package com.Aop;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;
import com.Action.StudentAction;

public class LogRegiste implements MethodInterceptor {

public Object invoke(MethodInvocation invocation) throws Throwable{
Logger log=Logger.getLogger(invocation.getClass());
log.info("您调用了StudentAction类的 " + invocation.getMethod() + "方法");
return invocation.proceed();
}
}
(2)以下是我的Action类,页面中是通过学号ID查询学生信息的,在此Dao类我就不给出了。
package com.Action;

import java.util.List;
import com.Dao.StudentDao;
import com.model.Student;
import com.opensymphony.xwork2.ActionSupport;

public class StudentAction extends ActionSupport{
private StudentDao studentDao;
private Student student;
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public StudentDao getStudentDao() {
return studentDao;
}
public void setStudentDao(StudentDao studentDao) {
this.studentDao = studentDao;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}

public String findStudentById() {
student = studentDao.findStudentById(id);
                   if(sutdent!=null){
     return SUCCESS;
                   }
                   return ERROR;
}
}
(3)下面是applicationContext.xml文件中的部分代码:
<bean id="studentAction" class="com.Action.StudentAction">
<property name="studentDao" ref="studentDao" />
</bean>

<bean id="logRegiste" class="com.Aop.LogRegiste">
</bean>

<bean id="performancePointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*Student" />
</bean>

<bean id="logRegisteAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="logRegiste" />
<property name="pointcut" ref="performancePointcut" />
</bean>

<bean id="student" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyTargetClass" value="true"/>
<property name="target" ref="studentAction" />
<property name="interceptorNames" value="logRegisteAdvisor" />
</bean>
    id为performancePointcut的<bean>是配置了一个切点,pattern属性用于指定方法匹配所使用的切点模板,它的值是一个正则表达式,也就是应该匹配任何类里名为Student的方法。
    在定义了切点之后,就需要把它与通知相关联,下面的<bean>就是配置了一个通用者。DefaultPointcutAdvisor是个通知者类,它只是把通知关联到一个切点。这里,advice属性设置为对logRegiste的引用,pointcut属性引用了performancePointcut,它就是匹配Student()方法的切点。
    RegexpMethodPointcutAdvisor是个特殊的通知者类,可以在一个Bean里定义切点和通知者,如下:
<bean id="logRegisteAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    <property name="advice" ref="logRegiste"/>
    <property name="pattern" value=".*Student"/>
</bean>
    这一个<bean>完成了两个Bean的工作,等效于一个performancePointcut Bean和前面a定义的那个logRegisteAdvisor Bean。
    最后配置了一个代理Bean,作为被通知者通知的Bean,它必须是要被代理的。Spring的ProxyFactoryBean是个工厂Bean,用于生成一个代理,把一个或多个拦截者和通知者应用到Bean。
    target属性是设置需要被代理的Bean,这里是studentAction。interceptorNames属性是设置哪个通知者要应用于被代理的Bean。
    这里我把proxyTargetClass属性的值设置为true,因为我的StudentAction类没有实现任何接口(这里只是作为一个例子,一般在工程中都会实现接口的),这时自动会用CBLIG进行代理。如果StudentAction实现了某个接口,就不需要配置proxyTargetClass属性,而是配置proxyInterfaces属性,该属性的值就是StudentAction实现的那个或那些接口。proxyInterfaces属性也可以省略,这是因为当StudentAction实现了接口时,系统会采用JDK进行代理,当没有配置proxyInterfaces属性时,JDK代理会创建StudentAction所实现的接口的所有方法的类,否则会创建实现了配置中的那些接口的类。
(4)下面这个<action>是struts.xml中的配置,name是页面上的请求, class设置为代理工厂类(ProxyFactoryBean)Bean的id
<action name="selectStudent" class="student" method="findStudentById">
      <result name="success">/student.jsp</result>
</action>
   

你可能感兴趣的:(DAO,spring,编程,bean,正则表达式)