最近一直在學java的spring boot,一直沒有弄明白aop面向切面編程是什么意思。看到一篇文章寫得很清楚,終於弄明白了,原來跟python的裝飾器一樣的效果。http://www.cnblogs.com/yanbincn/archive/2012/06/01/2530377.html
Aspect Oriented Programming 面向切面編程。解耦是程序員編碼開發過程中一直追求的。AOP也是為了解耦所誕生。
具體思想是:定義一個切面,在切面的縱向定義處理方法,處理完成之后,回到橫向業務流。
AOP 在Spring框架中被作為核心組成部分之一,的確Spring將AOP發揮到很強大的功能。最常見的就是事務控制。工作之余,對於使用的工具,不免需要了解其所以然。學習了一下,寫了些程序幫助理解。
AOP 主要是利用代理模式的技術來實現的。
靜態代理(代碼如下):
package com.practice.proxypattern; public interface ITalk { public void talk(String msg); }
package com.practice.proxypattern; public class PeopleTalk implements ITalk { private String username; private String age; public PeopleTalk(String username,String age) { this.username=username; this.age=age; } public void talk(String msg) { // TODO Auto-generated method stub System.out.println(msg+"你好,我是"+username+",我年齡是"+age); } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } }
package com.practice.proxypattern; import java.security.PublicKey; public class TalkProxy implements ITalk{ private ITalk talker; public TalkProxy(ITalk talker) { this.talker=talker; } public void talk(String msg) { // TODO Auto-generated method stub talker.talk(msg); } public void talk(String msg,String singname) { talker.talk(msg); sing(singname); } private void sing(String singname) { System.out.println("唱歌:"+singname); } }
package com.practice.proxypattern; public class ProxyPattern { public static void main(String[] args) { ITalk people=new PeopleTalk("AOP", "18"); people.talk("No ProXY Test"); System.out.println("-----------------------"); TalkProxy talker=new TalkProxy(people); talker.talk("ProXY Test","代理"); } }
運行結果如下:
No ProXY Test你好,我是AOP,我年齡是18
-----------------------
ProXY Test你好,我是AOP,我年齡是18
唱歌:代理
添加了一個新功能
以下是動態代理的代碼:
package com.practice.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynamicProxy implements InvocationHandler { //需要代理的目標類 private Object target; public Object bind(Object target) { this.target=target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub Object result=null; System.out.println("切面之前執行"); result=method.invoke(target, args); System.out.println("切面之后執行"); return result; } }
package com.practice.dynamicproxy; import com.practice.proxypattern.ITalk; import com.practice.proxypattern.PeopleTalk; public class Test { public static void main(String[] args) { ITalk iTalk=(ITalk) new DynamicProxy().bind(new PeopleTalk("DynamicProxy","18")); iTalk.talk("業務說明"); } }
運行結果如下:
切面之前執行
業務說明你好,我是DynamicProxy,我年齡是18
切面之后執行
同樣也添加了新功能 ,與python裝飾器的功能大同小異。