springAOP的各个概念、
说明:
* 切面
日志、安全性的框架、权限的检查等,总之和业务逻辑没有关系的都可以看做切面
* 通知
切面中的方法
* 切入点
只有符合切入点,才能把通知和目标方法结合在一起
* 连接点
客户端调用的方法
* 代理对象的方法=通知+目标方法
* aop:做到了代码块的重用
/**
* 切面的总的接口
* @author Administrator
*
*/
public interface Interceptor {
public void interceptor();
}
每个切面实现interceptor的接口
public class Logger implements Interceptor{
@Override
public void interceptor() {
System.out.println("logging");
}
}
/**
* 1、把日志、安全性框架、权限导入进去
* 2、把目标类导入进去
* 3、上述两类通过构造函数赋值
* @author Administrator
*
*/
public class SalaryInterceptor implements InvocationHandler{
private Logger logger;
private Security security;
private Privilege privilege;
private List<Interceptor> interceptorList;
private Object target;
public SalaryInterceptor(Logger logger,Security security,Privilege privilege,Object target,List<Interceptor> interceptorList){
this.logger = logger;
this.security = security;
this.privilege = privilege;
this.target = target;
this.interceptorList = interceptorList;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
/**
* 执行所有的切面中的通知
*/
for(Interceptor interceptor:interceptorList){
interceptor.interceptor();
}
method.invoke(this.target, args);
return null;
}
}
public class ProxyTest {
@Test
public void test(){
Logger logger = new Logger();
Privilege privilege = new Privilege();
Security security = new Security();
List<Interceptor> interceptorList = new ArrayList<Interceptor>();
interceptorList.add(logger);
interceptorList.add(privilege);
interceptorList.add(security);
SalaryManager target = new SalaryManagerImpl();
SalaryInterceptor interceptor = new SalaryInterceptor(logger, security, privilege, target,interceptorList);
/**
* 1、目标类的类加载器
* 2、目标类的所有的接口
* 3、拦截器
*/
SalaryManager proxy = (SalaryManager) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor);
proxy.showSalary();//代理对象的代理方法
}
}
aop举例
public class Person {
private Long pid;
private String pname;
public Long getPid() throws Exception{
return pid;
}
public void setPid(Long pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
@Test
public void test() throws Exception{
Method method = Person.class.getMethod("getPid");
System.out.println(method.toString());
}//public java.lang.Long cn.itcast.spring0909.aop.xml.Person.getPid() throws java.lang.Exception
}
/**
* 目标接口
* @author Administrator
*
*/
public interface PersonDao {
public void savePerson();
public void updatePerson();
public void deletePerson();
public List<Person> getPerson();
}
public class PersonDaoImpl implements PersonDao{
@Override
public void savePerson() {
// TODO Auto-generated method stub
System.out.println("save person");
}
@Override
public void updatePerson() {
// TODO Auto-generated method stub
System.out.println("update person");
}
@Override
public void deletePerson() {
// TODO Auto-generated method stub
System.out.println("delete person");
}
@Override
public List<Person> getPerson() {
// TODO Auto-generated method stub
Person person = new Person();
person.setPid(1L);
person.setPname("aaa");
List<Person> personList = new ArrayList<Person>();
personList.add(person);
for(Person person2:personList){
System.out.println(person2.getPname());
}
return personList;
}
}
public class Transaction {
public void beginTransaction(){
System.out.println("begin transaction");
}
public void commit(){
System.out.println("commit");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
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.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<!--
1、引入AOP的命名空间
2、目标类
3、切面
4、拦截器 由spring内部实现
5、aop的配置
-->
<bean id="personDao" class="cn.itcast.spring0909.aop.xml.PersonDaoImpl"></bean>
<bean id="transaction" class="cn.itcast.spring0909.aop.xml.Transaction"></bean>
<!--
aop的配置
-->
<aop:config>
<!--
切入点表达式
expression
确定哪个类可以生成代理对象
id 唯一标识
-->
<aop:pointcut expression="execution(* cn.itcast.spring0909.aop.xml.PersonDaoImpl.*(..))" id="perform"/>
<!--
切面
-->
<aop:aspect ref="transaction">
<!--
前置通知
-->
<aop:before method="beginTransaction" pointcut-ref="perform"/>
<aop:after-returning method="commit" pointcut-ref="perform"/>
</aop:aspect>
</aop:config>
</beans>
/**
* 原理
* * 加载配置文件,启动spring容器
* * spring容器为bean创建对象
* * 解析aop的配置,会解析切入点表达式
* * 看纳入spring管理的那个类和切入点表达式匹配,如果匹配则会为该类创建代理对象
* * 代理对象的方法体的形成就是目标方法+通知
* * 客户端在context.getBean时,如果该bean有代理对象,则返回代理对象,如果没有代理对象则返回原来的对象
* @author Administrator
*
*/
public class PersonTest extends SpringHelper{
static{
path = "cn/itcast/spring0909/aop/xml/applicationContext.xml";
}
@Test
public void test(){
PersonDao personDao = (PersonDao)context.getBean("personDao");
personDao.updatePerson();
}
}
需要导入jar包