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(典型應用二)