AOP,Aspect Oriented Programing,面向切面编程。
如果想在无源码的项目(比如:此项目已交付使用,不便于直接在源码上修改)一些方法前面或者后面新增加一些功能(二次开发、功能扩展),则此时可以使用动态代理来处理。下面是一个示例:
UserDAO.java
package com.bebig.dao;

import com.bebig.model.User;

public interface UserDAO {
    
public void save(User u);
}

UserDAOImpl.java
package com.bebig.dao.impl;

import org.springframework.stereotype.Repository;

import com.bebig.dao.UserDAO;
import com.bebig.model.User;


@Repository
public class UserDAOImpl implements UserDAO {

    @Override
    
public void save(User u) {
        System.out.println(
"a user saved!");
    }


}

LogInterceptor.java(这里在原来方法前加了简单日志功能作为演示)
package com.bebig.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

//聚合方式,实现InvocationHandler接口
public class LogInterceptor implements InvocationHandler {
    
    
private Object target;
    
    
public Object getTarget() {
        
return target;
    }


    
public void setTarget(Object target) {
        
this.target = target;
    }


    
public void beforeMethod() {
        System.out.println(
"Logging start");
    }


    @Override
    
public Object invoke(Object proxy, Method m, Object[] args)
            
throws Throwable {
        
//在对象原来方法前加上自定义方法
        beforeMethod();
        
//调用对象的方法
        m.invoke(target, args);
        
        
return null;
    }

}

User.java
package com.bebig.model;

public class User {
    
private String username;
    
private String password;

    
public String getPassword() {
        
return password;
    }


    
public String getUsername() {
        
return username;
    }


    
public void setPassword(String password) {
        
this.password = password;
    }


    
public void setUsername(String username) {
        
this.username = username;
    }

}

UserService.java
package com.bebig.service;

import javax.annotation.Resource;
import org.springframework.stereotype.Service;

import com.bebig.dao.UserDAO;
import com.bebig.model.User;

@Service(
"userService")
public class UserService {
    
private UserDAO userDAO;

    
public void add(User u) {
        userDAO.save(u);

    }


    @Resource
    
public void setUserDAO(UserDAO userDAO) {
        
this.userDAO = userDAO;
    }


    
public UserDAO getUserDAO() {
        
return userDAO;
    }


}

beans.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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation
="
http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>

    
<!-- a service object; we will be profiling its methods -->
    
<context:annotation-config />
    
<context:component-scan base-package="com.bebig" />

</beans>

UserServiceTest.java(测试用例)
package com.bebig.service;

import java.lang.reflect.Proxy;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.bebig.aop.LogInterceptor;
import com.bebig.dao.UserDAO;
import com.bebig.dao.impl.UserDAOImpl;
import com.bebig.model.User;

public class UserServiceTest {

    @Test
    
public void testAdd() throws Exception {
        ApplicationContext cxt 
= new ClassPathXmlApplicationContext("beans.xml");
        
// ClassPathXmlApplicationContext cxt = new
        
// ClassPathXmlApplicationContext("beans.xml");

        UserService service 
= (UserService) cxt.getBean("userService");

        User u 
= new User();
        u.setUsername(
"Don");
        u.setPassword(
"123");
        service.add(u);
    }


    @Test
    
public void testProxy() {
        UserDAO userDAO 
= new UserDAOImpl();//被代理对象
        LogInterceptor li = new LogInterceptor();
        li.setTarget(userDAO);

        
//创建代理对象,并实现与被代理对象一样的接口
        UserDAO userDAOProxy = (UserDAO) Proxy.newProxyInstance(userDAO
                .getClass().getClassLoader(),
        
// new Class[]{userDAO.class},取得被代理对象所实现的接口,方法1
                userDAO.getClass().getInterfaces(),// 方法2
                li);// 实现方法

        userDAOProxy.save(
new User());

    }


}

 

1.     面向切面编程Aspect-Oriented-Programming

a)     是对面向对象的思维方式的有力补充

2.     好处:可以动态的添加和删除在切面上的逻辑而不影响原来的执行代码

a)     Filter(典型应用一)

b)     Struts2interceptor(典型应用二)