下面这是一个简单的spring ioc例子:
学生介绍自己的接口:
package com.bdqn.aop.dao;
public interface Student {
public void Introduce(String name);
}
实现类:
package com.bdqn.aop.dao.impl;
import com.bdqn.aop.dao.Student;
public class StudentImpl implements Student{
public void Introduce(String name) {
// TODO Auto-generated method stub
System.out.println("各位同学好,我的名字叫做"+name);
}
}
配置文件applicationContext.xml:
<?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="student" class="com.bdqn.aop.dao.impl.StudentImpl"/>
</beans>
测试类:
package com.bdqn.aop.dao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestStudent {
public static void main(String[] args) throws Exception{
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) ac.getBean("student");
student.Introduce("蜡笔小新");
}
}
控制台打印:
各位同学好,我的名字叫做蜡笔小新
===================================================================================
AOP ----切面编程
所谓切面编程:在不改变原方法(令为methodA)的定义与使用、也不改变原程序的流程的情况下,变更该methodA的功能。在变更时,最激动人心的时能获得methodA的类的对象,meahtoidA的参数,也可获得mehodA执行的结果,还能得到调用meahtoidA的对象。
简单理解:允许用户在指定地方,插入新的函数,
包括:
1 methodA运行前,执行用户指定的其它方法methodOther,然后返回
2 methodA运行完毕,执行用户指的其它方法methodOther,然后返回
3 在执行methodA的地方,变成执行在用户指定的其它方法methodOther,
在methodOther方法中, methodA运不运行,何时运行,随用户自行安排,然后返回
4 methodA执行出现异常时,执行用户指定的其它方法methodOther,然后返回。
产生动机:
在一个程序中,当我们要 使用一个方法(令为methodA);由于不同的用户对methodA的功能要 求不一样,因此在这个methodA的地方就出现了变化点。所以要在这个变化点上进行封装,留下一个可扩展的接口,便于日后修改维护。
本质:
1 Aop核心是一个适配器,把变动前的方法,与变动后的方法联接在一起。
2 这个适配器实现的核心是动态代理 Proxy机制
3 四个核心子接口:
a MethodBeforeAdvice ----methodA函数调用前执行用户定义的方法
b AfterReturningAdvice ----- methodA函数调后执行用户定义的方法
c MethodInterceptor -------彻底变更MethodA函数为用户定义的方法
d ThrowsAdvice------methodA函数调用出现异常执行用户定义的方法
===================================================================================
下面是aop 的例子:
1);在介绍自己的前面添加新功能(有请下一位同学来自我介绍)
增加:StudentBeforeAdvice方法,实现MethodBeforeAdvice接口
package com.bdqn.aop.dao;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class StudentBeforeAdvice implements MethodBeforeAdvice{
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
// TODO Auto-generated method stub
System.out.println("有请下一位同学上来自我介绍!");
}
}
配置文件:
<pre name="code" class="java"><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<span style="white-space:pre"> </span> <bean id="student" class="com.bdqn.aop.dao.impl.StudentImpl"/>
<bean id="studentBeforeAdvice" class="com.bdqn.aop.dao.StudentBeforeAdvice"></bean>
<bean id="newStudent" class="org.springframework.aop.framework.ProxyFactoryBean"
p:proxyInterfaces="com.bdqn.aop.dao.Student"
p:target-ref="student"
p:interceptorNames="studentBeforeAdvice"
/>
</beans>
测试:
package com.bdqn.aop.dao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestStudent {
public static void main(String[] args) throws Exception{
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) ac.getBean("newStudent");
student.Introduce("蜡笔小新");
}
}
控制台:
有请下一位同学上来自我介绍!
各位同学好,我的名字叫做蜡笔小新
2)在介绍自己的后面加入新功能(谢谢这位同学的介绍,大家掌声鼓励!)
添加StudentAfterAdvice类实现AfterReturningAdvice接口:
package com.bdqn.aop.dao;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class StudentAfterAdvice implements AfterReturningAdvice{
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
// TODO Auto-generated method stub
System.out.println("谢谢这位同学的介绍,大家掌声鼓励!");
}
}
配置文件:
<?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="student" class="com.bdqn.aop.dao.impl.StudentImpl"/>
<bean id="studentBeforeAdvice" class="com.bdqn.aop.dao.StudentBeforeAdvice"></bean>
<bean id="studengAfterAdvice" class="com.bdqn.aop.dao.StudentAfterAdvice"></bean>
<bean id="newStudent" class="org.springframework.aop.framework.ProxyFactoryBean"
p:proxyInterfaces="com.bdqn.aop.dao.Student"
p:target-ref="student"
p:interceptorNames="studentBeforeAdvice,studengAfterAdvice"
/>
</beans>
测试类:
package com.bdqn.aop.dao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestStudent {
public static void main(String[] args) throws Exception{
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) ac.getBean("newStudent");
student.Introduce("蜡笔小新");
}
}
控制台打印:
有请下一位同学上来自我介绍!
各位同学好,我的名字叫做蜡笔小新
谢谢这位同学的介绍,大家掌声鼓励!
3)修改原来的方法的内容,加一些业务的判断(判断同学是否已经介绍过了,如果已经介绍过了,就不用在介绍了)
增加StudentMethodInterceptor类实现MethodInterceptor接口:
package com.bdqn.aop.dao;
import java.util.HashSet;
import java.util.Set;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class StudentMethodInterceptor implements MethodInterceptor{
private Set stu = new HashSet();
public Object invoke(MethodInvocation invocation) throws Throwable {
Object result = null;
String sutdent = (String) invocation.getArguments()[0];
if(stu.contains(sutdent)){
System.out.println(sutdent+"你已经介绍过自己了,就不用在介绍了!");
}else{
//如果学生没有介绍过自己,执行目标方法,
result = invocation.proceed();
}
stu.add(sutdent);
return result;
}
}
配置文件:
<?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="student" class="com.bdqn.aop.dao.impl.StudentImpl"/>
<bean id="stuMethodInterceptor" class="com.bdqn.aop.dao.StudentMethodInterceptor"></bean>
<bean id="newStudent" class="org.springframework.aop.framework.ProxyFactoryBean"
p:proxyInterfaces="com.bdqn.aop.dao.Student"
p:target-ref="student"
p:interceptorNames="stuMethodInterceptor"
/>
</beans>
测试类:
package com.bdqn.aop.dao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestStudent {
public static void main(String[] args) throws Exception{
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) ac.getBean("newStudent");
student.Introduce("蜡笔小新");
student.Introduce("蜡笔小新");
}
}
控制台:
各位同学好,我的名字叫做蜡笔小新
蜡笔小新你已经介绍过自己了,就不用在介绍了!