代碼參見dynamic-proxy-AOP2
基于配置文件的方式的好處在于所謂的分層.所以號稱應該推薦使用這個方法
隨便了.代碼重新貼一次吧.
1.UserManager接口
 1package com.zyl.proxy;
 2
 3public interface UserManager {
 4    
 5    public void addUser(String name,String password);
 6    
 7    public void delUser(String id);
 8    
 9    public void modifyUser(int id, String name, String password);
10    
11}
2.UserManagerImpl(UserManager的實現類)
 1package com.zyl.proxy;
 2
 3public class UserManagerImpl implements UserManager {
 4
 5
 6    public void addUser(String name, String password) {
 7       //添加日志/安全性檢查
 8        //checksafe();
 9        //采用添加代理類的方法會如何?
10        System.out.println("UserManagerImpl.addUser()123");
11
12    }

13
14    @Override
15    public void delUser(String id) {
16        //添加日志/安全性檢查
17        //checksafe();
18           System.out.println("UserManagerImpl.delUser()");
19    }

20
21    @Override
22    public void modifyUser(int id, String name, String password) {
23        //添加日志/安全性檢查
24        //checksafe();
25           System.out.println("UserManagerImpl.modifyUser()");
26
27    }

28//    private void checksafe(){
29//        System.out.println("檢查安全性的方法");
30//    }
31}

32
3.感覺應該叫切面的接口?
1package com.zyl.proxy;
2//切入點
3public interface MySecurityManager {
4     public void checkSafe();
5}

6
4.實現
 1package com.zyl.proxy;
 2import org.aspectj.lang.annotation.Aspect;
 3import org.aspectj.lang.annotation.Before;
 4import org.aspectj.lang.annotation.Pointcut;
 5
 6
 7public class MySecurityManagerImpl implements MySecurityManager {
 8
 9
10
11
12public void checkSafe() {
13    System.out.println("checkSafe安全性檢查");
14
15}

16}

17
這里的切面的代碼簡化很多.只要寫需要額外加入的方法即可.其他的聲明放在配置文件中
5.client
 1package com.zyl.ooxx;
 2
 3import org.springframework.beans.factory.BeanFactory;
 4import org.springframework.context.support.ClassPathXmlApplicationContext;
 5
 6import com.zyl.proxy.UserManager;
 7
 8
 9
10public class client {
11
12    public static void main(String[] args) {
13        //所有對象要從ioc中去取,所以之前這些對象要在xml中注冊
14        
15        //通過配置文件初始化bean工廠
16        BeanFactory factory =new ClassPathXmlApplicationContext("applicationContext.xml");
17        //通過bean工廠得到UserManager
18        UserManager usermanager=(UserManager)factory.getBean("userManagergb23122");
19        
20        usermanager.addUser("1""password");
21        System.out.println("------------");
22        usermanager.delUser("1");
23        
24        
25    }

26
27}

28
其實認真看.這個和annotation方式的代碼都一樣啊.
就只有4.MySecurityManagerImpl代碼的簡化.和6.配置文件的改變
6.配置文件
 1<?xml version="1.0" encoding="UTF-8"?>
 2<beans xmlns="http://www.springframework.org/schema/beans" 
 3    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 4    xmlns:context="http://www.springframework.org/schema/context" 
 5    xmlns:tx="http://www.springframework.org/schema/tx" 
 6    xmlns:aop="http://www.springframework.org/schema/aop" 
 7    xsi:schemaLocation="http://www.springframework.org/schema/beans 
 8http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
 9http://www.springframework.org/schema/context 
10http://www.springframework.org/schema/context/spring-context-2.5.xsd 
11http://www.springframework.org/schema/aop 
12http://www.springframework.org/schema/aop/spring-aop-2.5.xsd 
13http://www.springframework.org/schema/tx 
14http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> 
15
16
17
18<bean id="mySecurityManagerImp" class="com.zyl.proxy.MySecurityManagerImpl"/>
19<bean id="userManagergb23122" class="com.zyl.proxy.UserManagerImpl"/>
20
21<aop:config>
22   <!-- 配置切面 -->
23   <aop:aspect id="securityAspect" ref="mySecurityManagerImp">
24    <!-- 描述切入點 -->
25    <aop:pointcut id="allAddMethod13" expression="execution(* add*(..))"/>  <!-- 切入點的什么,類似@Pointcut("execution(* add*(..))") 前一種方法中的這個寫法 -->
26    <!-- 描述advice -->
27    <aop:before pointcut-ref="allAddMethod13" method="checkSafe"/><!-- 這個before標簽說明是之前執行的. 注意id的對應.method就是新加入的方法的方法名了-->
28   </aop:aspect>
29</aop:config>
30</beans>

這個..變化就很大了
具體看我的注釋吧.
參看前一種方式.就很好理解了
小結:
spring對aop的支持
 1.采用配置文件的方式
 2.將切面,切入點,通知等定義在配置文件中
 <aop:config>
   <!-- 配置切面 -->
   <aop:aspect id="securityAspect" ref="mySecurityManagerImp">
    <!-- 描述切入點 -->
    <aop:pointcut id="allAddMethod" expression="execution(* add*(..))"/>
    <!-- 描述advice -->
    <aop:before pointcut-ref="allAddMethod" method="checkSafe"/>
   </aop:aspect>
</aop:config>
--------------------
p.s 我們可以得到切入點方法的信息(如addUser的方法名,傳入參數的值)之前動態代理當時是怎么做的呢?
代碼如下:
 1public Object invoke(Object proxy, Method method, Object[] args)//args是傳遞過來的參數,比如name為張三
 2            throws Throwable 
 3        //調用任何方法前都會前調用invoke方法,所以我們在invoke方法前放置需要調用的代碼 如安全性檢查/log日志等等添加的方法
 4        //這里還可以加入一些邏輯判斷,是否加入安全性檢查
 5        checksafe();
 6         System.out.println("方法名是"+method.getName());
 7         for(int i=0;i<args.length;i++){
 8             System.out.println("哈哈"+args[i]);
 9         }

10         //臨時添加方法調用結束
11         //以下調用一般的方法
12        Object result=null;
13        
14        try{
15            method.invoke(targetObj,args); //真正的調用對象的實現的方法(非添加的那些方法)
16        }
catch(Exception e){
17            e.printStackTrace();
18        }

19        return result; //invoke方法需要返回一個對象.所以前面定義了一個Object result=null; 這里返回result
20    }
配置文件的方式:我們可以通過方法名來判斷是否添加切面的內容.可是如何取得切入點方法的方法名,傳入參數這些值呢?(比如addUser("男人都是","帥哥")可以取得方法名:addUser,男人都是,帥哥等參數)

  做法: 在通知中加入一個JoinPoint參數(大小寫敏感),這個參數spring會自動傳入,我們從JoinPoint中可以取得目標對象的相關信息,如參數,方法名等.
將切面實現類修改即可:
 1package com.zyl.proxy;
 2
 3import org.aspectj.lang.JoinPoint;
 4
 5
 6
 7public class MySecurityManagerImpl  {
 8
 9
10
11
12public void checkSafe(JoinPoint joinpoint) {
13    Object[] args=joinpoint.getArgs();//得到參數
14    for(int i=0;i<args.length;i++){
15        System.out.println("參數是:"+args[i]);
16    }

17    System.out.println("方法名是:"+joinpoint.getSignature().getName());
18    System.out.println("checkSafe安全性檢查");
19
20}

21}
JointPoint自然會取得相應的信息.
題外話:
1.切面默認的情況下不需要接口(MySecurityManager接口其實可以不必存在);
2.對于目標對象(UserManagerImpl類),默認情況下必須實現接口(jdk動態代理需要接口).
  如果不是用接口,我們要使用CGLIB庫的支持才可以.