spring配置aop的方式有哪些 spring aop 可以实现什么
spring aop\u5207\u9762\u7ec7\u5165\u65b9\u5f0f\u6709\u54ea\u4e9b1.\u901a\u77e5(Advice):
\u901a\u77e5\u5b9a\u4e49\u4e86\u5207\u9762\u662f\u4ec0\u4e48\u4ee5\u53ca\u4f55\u65f6\u4f7f\u7528\u3002\u63cf\u8ff0\u4e86\u5207\u9762\u8981\u5b8c\u6210\u7684\u5de5\u4f5c\u548c\u4f55\u65f6\u9700\u8981\u6267\u884c\u8fd9\u4e2a\u5de5\u4f5c\u3002
2.\u8fde\u63a5\u70b9(Joinpoint):
\u7a0b\u5e8f\u80fd\u591f\u5e94\u7528\u901a\u77e5\u7684\u4e00 \u4e2a\u201c\u65f6\u673a\u201d\uff0c\u8fd9\u4e9b\u201c\u65f6\u673a\u201d\u5c31\u662f\u8fde\u63a5\u70b9\uff0c\u4f8b\u5982\u65b9\u6cd5\u88ab\u8c03\u7528\u65f6\u3001\u5f02\u5e38\u88ab\u629b\u51fa\u65f6\u7b49\u7b49\u3002
3.\u5207\u5165\u70b9(Pointcut)
\u901a\u77e5\u5b9a\u4e49\u4e86\u5207\u9762\u8981\u53d1\u751f\u7684\u201c\u6545\u4e8b\u201d\u548c\u65f6\u95f4\uff0c\u90a3\u4e48\u5207\u5165\u70b9\u5c31\u5b9a\u4e49\u4e86\u201c\u6545\u4e8b\u201d\u53d1\u751f\u7684\u5730\u70b9\uff0c\u4f8b\u5982\u67d0\u4e2a\u7c7b\u6216\u65b9\u6cd5\u7684\u540d\u79f0\uff0cspring\u4e2d\u5141\u8bb8\u6211\u4eec\u65b9\u4fbf\u7684\u7528\u6b63\u5219\u8868\u8fbe\u5f0f\u6765\u6307\u5b9a
4.\u5207\u9762(Aspect)
\u901a\u77e5\u548c\u5207\u5165\u70b9\u5171\u540c\u7ec4\u6210\u4e86\u5207\u9762\uff1a\u65f6\u95f4\u3001\u5730\u70b9\u548c\u8981\u53d1\u751f\u7684\u201c\u6545\u4e8b\u201d
5.\u5f15\u5165(Introduction)
\u5f15\u5165\u5141\u8bb8\u6211\u4eec\u5411\u73b0\u6709\u7684\u7c7b\u6dfb\u52a0\u65b0\u7684\u65b9\u6cd5\u548c\u5c5e\u6027(spring\u63d0\u4f9b\u4e86\u4e00\u4e2a\u65b9\u6cd5\u6ce8\u5165\u7684\u529f\u80fd\uff09
6.\u76ee\u6807(Target)
\u5373\u88ab\u901a\u77e5\u7684\u5bf9\u8c61\uff0c\u5982\u679c\u6ca1\u6709AOP,\u90a3\u4e48\u5b83\u7684\u903b\u8f91\u5c06\u8981\u4ea4\u53c9\u522b\u7684\u4e8b\u52a1\u903b\u8f91\uff0c\u6709\u4e86AOP\u4e4b\u540e\u5b83\u53ef\u4ee5\u53ea\u5173\u6ce8\u81ea\u5df1\u8981\u505a\u7684\u4e8b\uff08AOP\u8ba9\u4ed6\u505a\u7231\u505a\u7684\u4e8b\uff09
7.\u4ee3\u7406(proxy)
\u5e94\u7528\u901a\u77e5\u7684\u5bf9\u8c61\uff0c\u8be6\u7ec6\u5185\u5bb9\u53c2\u89c1\u8bbe\u8ba1\u6a21\u5f0f\u91cc\u9762\u7684\u4ee3\u7406\u6a21\u5f0f
8.\u7ec7\u5165(Weaving)
\u628a\u5207\u9762\u5e94\u7528\u5230\u76ee\u6807\u5bf9\u8c61\u6765\u521b\u5efa\u65b0\u7684\u4ee3\u7406\u5bf9\u8c61\u7684\u8fc7\u7a0b\uff0c\u7ec7\u5165\u4e00\u822c\u53d1\u751f\u5728\u5982\u4e0b\u51e0\u4e2a\u65f6\u673a:
(1)\u7f16\u8bd1\u65f6\uff1a\u5f53\u4e00\u4e2a\u7c7b\u6587\u4ef6\u88ab\u7f16\u8bd1\u65f6\u8fdb\u884c\u7ec7\u5165\uff0c\u8fd9\u9700\u8981\u7279\u6b8a\u7684\u7f16\u8bd1\u5668\u624d\u53ef\u4ee5\u505a\u7684\u5230\uff0c\u4f8b\u5982AspectJ\u7684\u7ec7\u5165\u7f16\u8bd1\u5668
(2)\u7c7b\u52a0\u8f7d\u65f6\uff1a\u4f7f\u7528\u7279\u6b8a\u7684ClassLoader\u5728\u76ee\u6807\u7c7b\u88ab\u52a0\u8f7d\u5230\u7a0b\u5e8f\u4e4b\u524d\u589e\u5f3a\u7c7b\u7684\u5b57\u8282\u4ee3\u7801
(3)\u8fd0\u884c\u65f6\uff1a\u5207\u9762\u5728\u8fd0\u884c\u7684\u67d0\u4e2a\u65f6\u523b\u88ab\u7ec7\u5165,SpringAOP\u5c31\u662f\u4ee5\u8fd9\u79cd\u65b9\u5f0f\u7ec7\u5165\u5207\u9762\u7684\uff0c\u539f\u7406\u5e94\u8be5\u662f\u4f7f\u7528\u4e86JDK\u7684\u52a8\u6001\u4ee3\u7406\u6280\u672f
AOP\u6280\u672f\u5229\u7528\u4e00\u79cd\u79f0\u4e3a\u201c\u6a2a\u5207\u201d\u7684\u6280\u672f\uff0c\u89e3\u5256\u5c01\u88c5\u7684\u5bf9\u8c61\u5185\u90e8\uff0c\u5e76\u5c06\u90a3\u4e9b\u5f71\u54cd\u4e86\u591a\u4e2a\u7c7b\u7684\u516c\u5171\u884c\u4e3a\u5c01\u88c5\u5230\u4e00\u4e2a\u53ef\u91cd\u7528\u6a21\u5757\uff0c\u8fd9\u6837\u5c31\u80fd\u51cf\u5c11\u7cfb\u7edf\u7684\u91cd\u590d\u4ee3\u7801\uff0c\u964d\u4f4e\u6a21\u5757\u95f4\u7684\u8026\u5408\u5ea6\uff0c\u5e76\u6709\u5229\u4e8e\u672a\u6765\u7684\u53ef\u64cd\u4f5c\u6027\u548c\u53ef\u7ef4\u62a4\u6027\u3002AOP\u628a\u8f6f\u4ef6\u7cfb\u7edf\u5206\u4e3a\u4e24\u4e2a\u90e8\u5206\uff1a\u6838\u5fc3\u5173\u6ce8\u70b9\u548c\u6a2a\u5207\u5173\u6ce8\u70b9\u3002\u4e1a\u52a1\u5904\u7406\u7684\u4e3b\u8981\u6d41\u7a0b\u662f\u6838\u5fc3\u5173\u6ce8\u70b9\uff0c\u4e0e\u4e4b\u5173\u7cfb\u4e0d\u5927\u7684\u90e8\u5206\u662f\u6a2a\u5207\u5173\u6ce8\u70b9\u3002\u6a2a\u5207\u5173\u6ce8\u70b9\u7684\u4e00\u4e2a\u7279\u70b9\u662f\uff0c\u4ed6\u4eec\u7ecf\u5e38\u53d1\u751f\u5728\u6838\u5fc3\u5173\u6ce8\u70b9\u7684\u591a\u5904\uff0c\u800c\u5404\u5904\u90fd\u57fa\u672c\u76f8\u4f3c\u3002\u6bd4\u5982\u6743\u9650\u8ba4\u8bc1\u3001\u65e5\u5fd7\u3001\u4e8b\u52a1\u5904\u7406\u3002
\u5b9e\u73b0\u539f\u7406\u3000\u3000
\u524d\u9762\u5728\u5b66\u4e60\u4ee3\u7406\u6a21\u5f0f\u7684\u65f6\u5019\uff0c\u4e86\u89e3\u5230\u4ee3\u7406\u6a21\u5f0f\u5206\u4e3a\u52a8\u6001\u4ee3\u7406\u548c\u9759\u6001\u4ee3\u7406\u3002\u73b0\u5728\u6211\u4eec\u5c31\u4ee5\u4ee3\u7406\u6a21\u5f0f\u4e3a\u57fa\u7840\u5148\u5b9e\u73b0\u6211\u4eec\u81ea\u5df1\u7684AOP\u6846\u67b6\uff0c\u518d\u6765\u7814\u7a76Spring\u7684AOP\u7684\u5b9e\u73b0\u539f\u7406\u3002
\u5148\u4ee5\u9759\u6001\u4ee3\u7406\u5b9e\u73b0\uff0c\u9759\u6001\u4ee3\u7406\u5173\u952e\u662f\u5728\u4ee3\u7406\u5bf9\u8c61\u548c\u76ee\u6807\u5bf9\u8c61\u5b9e\u73b0\u5171\u540c\u7684\u63a5\u53e3\uff0c\u5e76\u4e14\u4ee3\u7406\u5bf9\u8c61\u6301\u6709\u76ee\u6807\u5bf9\u8c61\u7684\u5f15\u7528\u3002
\u516c\u5171\u63a5\u53e3\u4ee3\u7801\uff1a
1 public interface IHello {
2 /**
3 * \u4e1a\u52a1\u65b9\u6cd5
4 * @param str
5 */
6 void sayHello(String str);
7 }
\u76ee\u6807\u7c7b\u4ee3\u7801\uff1a
1 public class Hello implements IHello{
2 @Override
3 public void sayHello(String str) {
4 System.out.println("hello "+str);
5 }
6
7 }
\u4ee3\u7406\u7c7b\u4ee3\u7801\uff0c\u6211\u4eec\u7ed9\u5b83\u6dfb\u52a0\u65e5\u5fd7\u8bb0\u5f55\u529f\u80fd\uff0c\u5728\u65b9\u6cd5\u5f00\u59cb\u524d\u540e\u6267\u884c\u7279\u5b9a\u7684\u65b9\u6cd5\uff0c\u662f\u4e0d\u662f\u548cAOP\u7279\u522b\u50cf\u5462\uff1f
public class ProxyHello implements IHello{
private IHello hello;
public ProxyHello(IHello hello) {
super();
this.hello = hello;
}
@Override
public void sayHello(String str) {
Logger.start();//\u6dfb\u52a0\u7279\u5b9a\u7684\u65b9\u6cd5
hello.sayHello(str);
Logger.end();
}
}
\u65e5\u5fd7\u7c7b\u4ee3\u7801\uff1a
1 public class Logger {
2 public static void start(){
3 System.out.println(new Date()+ " say hello start...");
4 }
5
6 public static void end(){
7 System.out.println(new Date()+ " say hello end");
8 }
9 }
\u6d4b\u8bd5\u4ee3\u7801\uff1a
1 public class Test {
2 public static void main(String[] args) {
3 IHello hello = new ProxyHello(new Hello());//\u5982\u679c\u6211\u4eec\u9700\u8981\u65e5\u5fd7\u529f\u80fd\uff0c\u5219\u4f7f\u7528\u4ee3\u7406\u7c7b
4 //IHello hello = new Hello();//\u5982\u679c\u6211\u4eec\u4e0d\u9700\u8981\u65e5\u5fd7\u529f\u80fd\u5219\u4f7f\u7528\u76ee\u6807\u7c7b
5 hello.sayHello("\u660e\u5929");
6 }
7 }
\u8fd9\u6837\u6211\u4eec\u5c31\u5b9e\u73b0\u4e86\u4e00\u4e2a\u6700\u7b80\u5355\u7684AOP\uff0c\u4f46\u662f\u8fd9\u6837\u4f1a\u5b58\u5728\u4e00\u4e2a\u95ee\u9898\uff1a\u5982\u679c\u6211\u4eec\u50cfHello\u8fd9\u6837\u7684\u7c7b\u5f88\u591a\uff0c\u90a3\u4e48\uff0c\u6211\u4eec\u662f\u4e0d\u662f\u8981\u53bb\u5199\u5f88\u591a\u4e2aHelloProxy\u8fd9\u6837\u7684\u7c7b\u5462\u3002\u5176\u5b9e\u4e5f\u662f\u4e00\u79cd\u5f88\u9ebb\u70e6\u7684\u4e8b\u3002\u5728jdk1.3\u4ee5\u540e\uff0cjdk\u8ddf\u6211\u4eec\u63d0\u4f9b\u4e86\u4e00\u4e2aAPI java.lang.reflect.InvocationHandler\u7684\u7c7b\uff0c \u8fd9\u4e2a\u7c7b\u53ef\u4ee5\u8ba9\u6211\u4eec\u5728JVM\u8c03\u7528\u67d0\u4e2a\u7c7b\u7684\u65b9\u6cd5\u65f6\u52a8\u6001\u7684\u4e3a\u4e9b\u65b9\u6cd5\u505a\u4e9b\u4ec0\u4e48\u4e8b\u3002\u4e0b\u9762\u6211\u4eec\u5c31\u6765\u5b9e\u73b0\u52a8\u6001\u4ee3\u7406\u7684\u5b9e\u73b0\u3002
\u52a8\u6001\u4ee3\u7406\u5b9e\u73b0\u4e3b\u8981\u662f\u5b9e\u73b0InvocationHandler\uff0c\u5e76\u4e14\u5c06\u76ee\u6807\u5bf9\u8c61\u6ce8\u5165\u5230\u4ee3\u7406\u5bf9\u8c61\u4e2d\uff0c\u5229\u7528\u53cd\u5c04\u673a\u5236\u6765\u6267\u884c\u76ee\u6807\u5bf9\u8c61\u7684\u65b9\u6cd5\u3002
\u63a5\u53e3\u5b9e\u73b0\u4e0e\u9759\u6001\u4ee3\u7406\u76f8\u540c\uff0c\u4ee3\u7406\u7c7b\u4ee3\u7801\uff1a
1 public class DynaProxyHello implements InvocationHandler{
2
3 private Object target;//\u76ee\u6807\u5bf9\u8c61
4 /**
5 * \u901a\u8fc7\u53cd\u5c04\u6765\u5b9e\u4f8b\u5316\u76ee\u6807\u5bf9\u8c61
6 * @param object
7 * @return
8 */
9 public Object bind(Object object){
10 this.target = object;
11 return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this);
12 }
13
14 @Override
15 public Object invoke(Object proxy, Method method, Object[] args)
16 throws Throwable {
17 Object result = null;
18 Logger.start();//\u6dfb\u52a0\u989d\u5916\u7684\u65b9\u6cd5
19 //\u901a\u8fc7\u53cd\u5c04\u673a\u5236\u6765\u8fd0\u884c\u76ee\u6807\u5bf9\u8c61\u7684\u65b9\u6cd5
20 result = method.invoke(this.target, args);
21 Logger.end();
22 return result;
23 }
24
25 }
\u6d4b\u8bd5\u7c7b\u4ee3\u7801\uff1a
1 public class DynaTest {
2 public static void main(String[] args) {
3 IHello hello = (IHello) new DynaProxyHello().bind(new Hello());//\u5982\u679c\u6211\u4eec\u9700\u8981\u65e5\u5fd7\u529f\u80fd\uff0c\u5219\u4f7f\u7528\u4ee3\u7406\u7c7b
4 //IHello hello = new Hello();//\u5982\u679c\u6211\u4eec\u4e0d\u9700\u8981\u65e5\u5fd7\u529f\u80fd\u5219\u4f7f\u7528\u76ee\u6807\u7c7b
5 hello.sayHello("\u660e\u5929");
6 }
7 }
\u770b\u5b8c\u4e0a\u9762\u7684\u4ee3\u7801\u53ef\u80fd\u548cSpring AOP\u76f8\u6bd4\u6709\u4e00\u4e2a\u95ee\u9898\uff0c\u65e5\u5fd7\u7c7b\u53ea\u80fd\u5728\u65b9\u6cd5\u524d\u540e\u6253\u5370\uff0c\u4f46\u662fAOP\u5e94\u8be5\u662f\u53ef\u4ee5\u5728\u6ee1\u8db3\u6761\u4ef6\u5c31\u53ef\u4ee5\u6267\u884c\uff0c\u6240\u6709\u662f\u5426\u53ef\u4ee5\u5c06DynaPoxyHello\u5bf9\u8c61\u548c\u65e5\u5fd7\u64cd\u4f5c\u5bf9\u8c61(Logger)\u89e3\u8026\u5462\uff1f
\u770b\u4e0b\u9762\u4ee3\u7801\u5b9e\u73b0\uff0c\u5c06\u5c06DynaPoxyHello\u5bf9\u8c61\u548c\u65e5\u5fd7\u64cd\u4f5c\u5bf9\u8c61(Logger)\u89e3\u8026\uff1a
\u6211\u4eec\u8981\u5728\u88ab\u4ee3\u7406\u5bf9\u8c61\u7684\u65b9\u6cd5\u524d\u9762\u6216\u8005\u540e\u9762\u53bb\u52a0\u4e0a\u65e5\u5fd7\u64cd\u4f5c\u4ee3\u7801(\u6216\u8005\u662f\u5176\u5b83\u64cd\u4f5c\u7684\u4ee3\u7801)\uff0c\u90a3\u4e48\uff0c\u6211\u4eec\u53ef\u4ee5\u62bd\u8c61\u51fa\u4e00\u4e2a\u63a5\u53e3\uff0c\u8fd9\u4e2a\u63a5\u53e3\u91cc\u5c31\u53ea\u6709\u4e24\u4e2a\u65b9\u6cd5\uff1a\u4e00\u4e2a\u662f\u5728\u88ab\u4ee3\u7406\u5bf9\u8c61\u8981\u6267\u884c\u65b9\u6cd5\u4e4b\u524d\u6267\u884c\u7684\u65b9\u6cd5,\u6211\u4eec\u53d6\u540d\u4e3astart\uff0c\u7b2c\u4e8c\u4e2a\u65b9\u6cd5\u5c31\u662f\u5728\u88ab\u4ee3\u7406\u5bf9\u8c61\u6267\u884c\u65b9\u6cd5\u4e4b\u540e\u6267\u884c\u7684\u65b9\u6cd5,\u6211\u4eec\u53d6\u540d\u4e3aend\u3002
Logger\u7684\u63a5\u53e3\uff1a
1 public interface ILogger {
2 void start(Method method);
3 void end(Method method);
4 }
Logger\u7684\u63a5\u53e3\u5b9e\u73b0\uff1a
1 public class DLogger implements ILogger{
2 @Override
3 public void start(Method method) {
4 System.out.println(new Date()+ method.getName() + " say hello start...");
5 }
6 @Override
7 public void end(Method method) {
8 System.out.println(new Date()+ method.getName() + " say hello end");
9 }
10 }
\u52a8\u6001\u4ee3\u7406\u7c7b\uff1a
1 public class DynaProxyHello1 implements InvocationHandler{
2 //\u8c03\u7528\u5bf9\u8c61
3 private Object proxy;
4 //\u76ee\u6807\u5bf9\u8c61
5 private Object target;
6
7 public Object bind(Object target,Object proxy){
8 this.target=target;
9 this.proxy=proxy;
10 return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this);
11 }
12
13
14 @Override
15 public Object invoke(Object proxy, Method method, Object[] args)
16 throws Throwable {
17 Object result = null;
18 //\u53cd\u5c04\u5f97\u5230\u64cd\u4f5c\u8005\u7684\u5b9e\u4f8b
19 Class clazz = this.proxy.getClass();
20 //\u53cd\u5c04\u5f97\u5230\u64cd\u4f5c\u8005\u7684Start\u65b9\u6cd5
21 Method start = clazz.getDeclaredMethod("start", new Class[]{Method.class});
22 //\u53cd\u5c04\u6267\u884cstart\u65b9\u6cd5
23 start.invoke(this.proxy, new Object[]{this.proxy.getClass()});
24 //\u6267\u884c\u8981\u5904\u7406\u5bf9\u8c61\u7684\u539f\u672c\u65b9\u6cd5
25 method.invoke(this.target, args);
26 //\u53cd\u5c04\u5f97\u5230\u64cd\u4f5c\u8005\u7684end\u65b9\u6cd5
27 Method end = clazz.getDeclaredMethod("end", new Class[]{Method.class});
28 //\u53cd\u5c04\u6267\u884cend\u65b9\u6cd5
29 end.invoke(this.proxy, new Object[]{method});
30 return result;
31 }
32
33 }
\u6d4b\u8bd5\u4ee3\u7801\uff1a
1 public class DynaTest1 {
2 public static void main(String[] args) {
3 IHello hello = (IHello) new DynaProxyHello1().bind(new Hello(),new DLogger());//\u5982\u679c\u6211\u4eec\u9700\u8981\u65e5\u5fd7\u529f\u80fd\uff0c\u5219\u4f7f\u7528\u4ee3\u7406\u7c7b
4 //IHello hello = new Hello();//\u5982\u679c\u6211\u4eec\u4e0d\u9700\u8981\u65e5\u5fd7\u529f\u80fd\u5219\u4f7f\u7528\u76ee\u6807\u7c7b
5 hello.sayHello("\u660e\u5929");
6 }
7 }
\u901a\u8fc7\u4e0a\u9762\u4f8b\u5b50\uff0c\u53ef\u4ee5\u53d1\u73b0\u901a\u8fc7\u52a8\u6001\u4ee3\u7406\u548c\u53d1\u5c04\u6280\u672f\uff0c\u5df2\u7ecf\u57fa\u672c\u5b9e\u73b0\u4e86AOP\u7684\u529f\u80fd\uff0c\u5982\u679c\u6211\u4eec\u53ea\u9700\u8981\u5728\u65b9\u6cd5\u6267\u884c\u524d\u6253\u5370\u65e5\u5fd7\uff0c\u5219\u53ef\u4ee5\u4e0d\u5b9e\u73b0end()\u65b9\u6cd5\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u63a7\u5236\u6253\u5370\u7684\u65f6\u673a\u4e86\u3002\u5982\u679c\u6211\u4eec\u60f3\u8ba9\u6307\u5b9a\u7684\u65b9\u6cd5\u6253\u5370\u65e5\u5fd7\uff0c\u6211\u4eec\u53ea\u9700\u8981\u5728invoke\uff08\uff09\u65b9\u6cd5\u4e2d\u52a0\u4e00\u4e2a\u5bf9method\u540d\u5b57\u7684\u5224\u65ad\uff0cmethod\u7684\u540d\u5b57\u53ef\u4ee5\u5199\u5728xml\u6587\u4ef6\u4e2d\uff0c\u8fd9\u6837\u6211\u4eec\u5c31\u53ef\u4ee5\u5b9e\u73b0\u4ee5\u914d\u7f6e\u6587\u4ef6\u8fdb\u884c\u89e3\u8026\u4e86\uff0c\u8fd9\u6837\u6211\u4eec\u5c31\u5b9e\u73b0\u4e86\u4e00\u4e2a\u7b80\u5355\u7684spring aop\u6846\u67b6\u3002
1. 基于xml配置文件的代理配置方式
这种方式在2.0以后很少用了,原因是配置项过多,过于繁琐。但对于理解Spring AOP还是很有帮助的
1.1 定义通知
<bean id="advice" class="yourAdviceImpl" />
1.2 定义切点
要定义一个切点,可以选择使用正则表达式方式声明的切点或者AspectJ方式声明的切点。对正则表达式切点,使用Perl5RegexpMethodPointcut或JdkRegexpMethodPointcut(Java
1.4以上版本,不需要Jakarta ORO的支持了);对AspectJ切点,使用AspectJExpressPointcut
<bean id="pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value="yourRegularExpression" />
</bean>
<bean id="pointcut" class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
<property name="expression" value="yourAspectJExpression" />
</bean>
1.3 定义通知者
DefaultPointcutAdvisor是Spring提供的默认通知者,它需要提供通知和切点的引用。
Spring也提供了RegexpMethodPointcutAdvisor和AspectJExpressionPointcutAdvisor来对应两种声明切点的方式,不用再单独定义切点。
<bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="advice" />
<property name="pointcut" ref="pointcut" />
</bean>
<bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="advice" />
<property name="pattern" value="yourRegularExpression" />
</bean>
<bean id="advisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
<property name="advice" ref="advice" />
<property name="expression" value="yourAspectjExpression" />
</bean>
1.4 定义ProxyFactoryBean
<bean id="yourBean" class="org.springframework.aop.framework.ProxyFactoryBean>
<property name="target" ref="yourTargetBean" />
<property name="interceptorNames" value="advisor" />
<property name="proxyInterfaces" value="interfaceClass" />
</bean>
interceptorNames和proxyInterfaces都是数组属性,所以可以声明要使用的一个list,也可以让Spring自动把单个值转化为数组
上面明确定义了要对那个targetBean应用代理生成切面实例。如果不想限制targetBean,可以让Spring为所有匹配切点声明的bean生成切面实例,这样就不用一个个定义ProxyFactoryBean了,只需要定义
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
这是一个BeanPostProcessor,所以Spring会自动识别并在bean的声明周期使用
2 利用2.0以后使用aop标签
<aop:config>
<aop:aspect ref="">
<aop:pointcut id="performance" expression="execution(* *.perform(..))" />
<aop:before method="" pointcut-ref="performance" />
<aop:before method="" pointcut="execution(* *.perform(..))" />
<aop:after-returning method="" pointcut="execution(* *.perform(..))" />
<aop:after-throwing method="" pointcut="execution(* *.perform(..))" />
</aop:aspect>
</aop:config>
3 利用Annotation
3.1 利用@Aspect将一个POJO类声明为一个切面。
3.2 定义切点
@Pointcut("execution(* *.perform(..))")
public void performance(){}
通过@Pointcut定义的切点的名字就是它所注解的方法的名字,因此例子中的切点名字是
performance()。这里声明的performance()方法实际圣只是一个标记,为@Pointcut提供附加的点,并不要求有实际意义。
3.3 定义通知
对要执行切面的方法,通过@Before("performance()"),@AfterReturning
("performance()")来定义通知。注意这里提供的切点名称,是performance(),而不是performance
如果对上面的两点不是很理解,也可以省略@Pointcut,而将AspectJ表达式直接定义在@Before等通知中,将上面的两步合为一步,如@Before("execution(* *.perform(..))")
3.4 通知Spring创建代理
<aop:aspectj-autoproxy>
这实际上相当于声明了一个AnnotationAwareAspectJAutoProxyCreator,从而根据@Pointcut声明的切点来自动代理匹配的bean实例
4 在Spring中结合进AspectJ
对于超出Spring AOP支持范围的,可以采用这种方式。只需要在Spring中配置AspectJ的Class实例时让Spring能够获得AspectJ类的实例就可以了,比如
<bean class="a_aspectj_class" factory-method="aspectOf">
<preperty .... />
</bean>
绛旓細1. 鍩轰簬xml閰嶇疆鏂囦欢鐨勪唬鐞閰嶇疆鏂瑰紡 杩欑鏂瑰紡鍦2.0浠ュ悗寰堝皯鐢ㄤ簡锛屽師鍥犳槸閰嶇疆椤硅繃澶氾紝杩囦簬绻佺悙銆備絾瀵逛簬鐞嗚ВSpring AOP杩樻槸寰堟湁甯姪鐨 1.1 瀹氫箟閫氱煡 <bean id="advice" class="yourAdviceImpl" /> 1.2 瀹氫箟鍒囩偣 瑕佸畾涔変竴涓垏鐐癸紝鍙互閫夋嫨浣跨敤姝e垯琛ㄨ揪寮忔柟寮忓0鏄庣殑鍒囩偣鎴栬匒spectJ鏂瑰紡澹版槑鐨勫垏鐐广傚姝e垯...
绛旓細绗竴绉嶏細娉ㄨВ閰嶇疆AOP 娉ㄨВ閰嶇疆AOP锛堜娇鐢 AspectJ 绫诲簱瀹炵幇鐨勶級锛屽ぇ鑷村垎涓轰笁姝ワ細1. 浣跨敤娉ㄨВ@Aspect鏉ュ畾涔変竴涓垏闈紝鍦ㄥ垏闈腑瀹氫箟鍒囧叆鐐(@Pointcut),閫氱煡绫诲瀷(@Before, @AfterReturning,@After,@AfterThrowing,@Around).2. 寮鍙戦渶瑕佽鎷︽埅鐨勭被銆3. 灏嗗垏闈㈤厤缃埌xml涓紝褰撶劧锛屾垜浠篃鍙互浣跨敤鑷姩鎵弿Bean...
绛旓細Advisor锛氶氱煡鍣紝涔熷氨鏄垏闈紝PointcutAdvisor鍒囩偣閫氱煡鍣紝IntroductionAdvisor寮曠敤閫氱煡鍣銆傚湪鍒涘缓AOP浠g悊涔嬪墠闇瑕佹妸鐩稿叧鐨勫垏闈㈤厤缃В鏋愭垚涓婇潰绫诲浘涓殑鎺ュ彛瀛愮被鐨勫璞★紝瀵逛簬ProxyFactoryBean鏉ヨ锛屾病鏈夎繖涓繃绋嬶紝鍥犱负杩欑鏂瑰紡涓嬩笉鑳戒娇鐢ㄥ垏鐐广傚垏闈㈣В鏋愬畬鎴愪箣鍚庯紝鎶婅В鏋愬嚭鐨勯氱煡娣诲姞閫氱煡閾句腑锛孉OP浠g悊瀵硅薄寮曠敤璇ラ氱煡...
绛旓細鎺у埗鍙嶈浆锛歴pring閫氳繃鎺у埗鍙嶈浆瀹炵幇浜嗘澗鏁h﹀悎锛屽璞′滑缁欏嚭瀹冧滑鐨勪緷璧栵紝鑰屼笉鏄垱寤烘垨鏌ユ壘渚濊禆鐨勫璞′滑銆傞潰鍚戝垏闈㈢殑缂栫▼(aop)锛歴pring鏀寔闈㈠悜鍒囬潰鐨勭紪绋嬶紝骞朵笖鎶婂簲鐢ㄤ笟鍔¢昏緫鍜岀郴缁熸湇鍔″垎寮銆傚鍣細spring鍖呭惈骞剁鐞嗗簲鐢ㄤ腑瀵硅薄鐨勭敓鍛藉懆鏈熷拰閰嶇疆銆俶vc妗嗘灦锛歴pring鐨剋eb妗嗘灦鏄釜绮惧績璁捐鐨勬鏋讹紝鏄痺eb妗嗘灦鐨勪竴涓緢...
绛旓細濡傛灉鎴戜滑鍙渶瑕佸湪鏂规硶鎵ц鍓嶆墦鍗版棩蹇楋紝鍒欏彲浠ヤ笉瀹炵幇end()鏂规硶锛岃繖鏍峰氨鍙互鎺у埗鎵撳嵃鐨勬椂鏈轰簡銆傚鏋滄垜浠兂璁╂寚瀹鐨勬柟娉鎵撳嵃鏃ュ織锛屾垜浠彧闇瑕佸湪invoke锛堬級鏂规硶涓姞涓涓method鍚嶅瓧鐨勫垽鏂紝method鐨勫悕瀛楀彲浠ュ啓鍦▁ml鏂囦欢涓紝杩欐牱鎴戜滑灏卞彲浠ュ疄鐜颁互閰嶇疆鏂囦欢杩涜瑙h︿簡锛岃繖鏍锋垜浠氨瀹炵幇浜嗕竴涓畝鍗曠殑spring aop妗嗘灦銆
绛旓細浣跨敤aspectj瀹炵幇aop鏈涓ょ鏂瑰紡锛氾紙1锛夊熀浜巃spectj鐨剎ml閰嶇疆锛涳紙2锛夊熀浜巃spectj鐨勬敞瑙f柟寮忥紱鍩轰簬aspectj鐨剎ml閰嶇疆锛氾紙1锛夊鍏ョ浉鍏崇殑AOP鐨jar鍖 锛2锛夊垱寤Spring鏍稿績閰嶇疆鏂囦欢锛屽鍏aop鐨绾︽潫 锛3锛変娇鐢ㄨ〃杈惧紡閰嶇疆鍒囧叆鐐 甯哥敤鐨勮〃杈惧紡锛歟xecution锛<璁块棶淇グ绗>?<杩斿洖绫诲瀷><鏂规硶鍚>(<鍙傛暟>)<寮傚父>锛夛紙4锛...
绛旓細spring AOP涓嶆槸鐢ㄥ弽灏勫疄鐜扮殑锛岃宐ean鐨勫垱寤轰竴鑸槸杩欐牱鍋氱殑銆俿pring閲屼富瑕侀氳繃Java鍔ㄦ佷唬鐞嗘帴鍙c乧glib鐢熸垚瀛愮被銆丄spectJ杩欎笁绉鏂瑰紡鏉ュ疄鐜癆OP銆傞氳繃AOP杩涜澹版槑寮忎簨鍔$鐞嗗簲璇ユ槸澶у鐢ㄧ殑鏈澶氱殑鍚с傚儚鏉冮檺鏍¢獙鍜屾棩蹇楄褰曡櫧鐒朵篃鍏峰涓瀹氱殑妯垏鎬ч渶姹傦紝浣嗗ソ鍍忓緢灏戞嬁spring鏉ュ仛锛屾潈闄愭帶鍒舵鏋跺掓槸鍙互鑰冭檻涓巗pring杩涜...
绛旓細AspectJAwareAdvisorAutoProxyCreator鐨刾ostProcessAfterInitialization鏂规硶鍐嶅叾鐖剁被AbstractAutoProxyCreator涓疄鐜帮紝鍏朵細瀵瑰凡缁忓疄渚嬪寲鐨刡ean杩涜wrap銆傝屽bean杩涜wrap鐨勬椂鍊欙紝灏辨槸浣跨敤ProxyFactory createAopProxy锛屾渶缁堜細璧板埌DefaultAopProxyFactory鐨刢reateAopProxy鏂规硶銆傚彲浠ョ湅鍒帮細aop鐨鍔熻兘涔熸槸鍊熷姪spring瀵筨ean鐨...
绛旓細灏忓瀷椤圭洰涓嶉噸瑕侊紝闅忎究浣犳庝箞鎶樿吘閮藉彲浠ワ紒 濡傛灉椤圭洰绋嶅井澶т竴浜涳紝鐢aop鐨璇濅細寰堝ソ缁存姢銆傛敞鍏鏂瑰紡涓昏鏈塨efore(涔嬪墠)锛宎fter(涔嬪悗), around(鐜粫)杩欓噷鏈変竴涓spring aop鐨勫皬渚嬪瓙锛屼綘鍙互鐪嬩竴涓嬶紝鑷繁璇曢獙涓涓嬪氨浠涔堥兘瑙e喅浜 http://www.javalinux.me/?p=188 ...
绛旓細涓句釜鍒楀瓙锛 缁欎笅闈㈢殑鏂规硶鍔犱笂鏃ュ織璁板綍锛 public void save(Object data){ //淇濆瓨鍒版暟鎹簱閫昏緫 } 閫氳繃Spring AOP鐨勬柟寮忛厤缃鏃ュ織鍚庯紝鏈缁堢▼搴忔墽琛屾椂锛堜篃璁告槸鍙嶅皠锛屼篃璁告槸淇敼class锛夛紝瀹為檯涓婂湪鎵цsave(obj)鏃讹紝鎵ц浜嗕笅闈㈢殑閫昏緫锛 log.info("寮濮嬩繚瀛");save(obj);log.info("缁撴潫淇濆瓨...