Spring Aop
代理机制
静态代理机制
代理对象和被代理对象必须实现同一个接口 可以按业务分开 不同服务呼叫不同业务对象
动态代理机制
设计一个类实现java.lang.reflect.InvocationHandler 于原有业务不相干 不用知道会调用谁
AOP术语
Cross-cutting concern 横切到业务流程中
Aspect 把Cross-cutting concern组织起来 设计成可重用的对象 AOP强调独立 重用时不用做任何的修改
Advice Aspect 的具体实现 在java中就是具体的类
Joinpoint 插入点和时机
Pointcut 组织Advice和Joinpoint
Target 被Advice应用的对象和目标
Introduction 对于一个现存的类 Introduction可以增加行为 而不用修改改类的程序
Proxy
Weave Advice被应用于对象之上的过程为织入
Advice
BeforeAdvice
例子
![](https://p-blog.csdn.net/images/p_blog_csdn_net/RainyTooo/sssss.GIF)
IHello.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
interface
IHello
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public void hello(String name);
}
HelloSpeaker.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
HelloSpeaker
implements
IHello
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public void hello(String name)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
System.out.println("hello !" + name);
}
}
LogBeforeAdvice.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
java.lang.reflect.Method;
import
java.util.logging.Level;
import
java.util.logging.Logger;
import
org.springframework.aop.MethodBeforeAdvice;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
LogBeforeAdvice
implements
MethodBeforeAdvice
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
private Logger logger=Logger.getLogger(this.getClass().getName());
public void before(Method method, Object[] args, Object target)throws Throwable
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
logger.log(Level.INFO, "method starts....", method);
}
}
beans-config.xml
<?
xml version="1.0" encoding="UTF-8"
?>
<!
DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
beans
>
<
bean
id
="logBeforeAdvice"
class
="com.ergal.spring.LogBeforeAdvice"
/>
<
bean
id
="helloSpeaker"
class
="com.ergal.spring.HelloSpeaker"
/>
<
bean
id
="helloProxy"
class
="org.springframework.aop.framework.ProxyFactoryBean"
>
<
property
name
="proxyInterfaces"
>
<
value
>
com.ergal.spring.IHello
</
value
>
</
property
>
<
property
name
="target"
>
<
ref
bean
="helloSpeaker"
/>
</
property
>
<
property
name
="interceptorNames"
>
<
list
>
<
value
>
logBeforeAdvice
</
value
>
</
list
>
</
property
>
</
bean
>
</
beans
>
SpringDemo.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.support.FileSystemXmlApplicationContext;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
SpringDemo
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public static void main(String[] args)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
ApplicationContext context=new FileSystemXmlApplicationContext("beans-config.xml");
IHello helloproxy=(IHello)context.getBean("helloProxy");
helloproxy.hello("Rainytooo");
}
}
测试结果
信息: Pre-instantiating singletons in factory [org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [logBeforeAdvice,helloSpeaker,helloProxy]; root of BeanFactory hierarchy]
2006-9-30 0:31:17 org.springframework.aop.framework.DefaultAopProxyFactory <clinit>
信息: CGLIB2 not available: proxyTargetClass feature disabled
2006-9-30 0:31:17 com.ergal.spring.LogBeforeAdvice before
信息: method starts....
hello !Rainytooo
AfterAdvice 稍加修改即可
AroundAdvice
LogInterceptor.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
java.util.logging.Level;
import
java.util.logging.Logger;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.aopalliance.intercept.MethodInterceptor;
import
org.aopalliance.intercept.MethodInvocation;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
LogInterceptor
implements
MethodInterceptor
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
private Logger logger=Logger.getLogger(this.getClass().getName());
public Object invoke(MethodInvocation methodInvocation)throws Throwable
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
logger.log(Level.INFO, "method start...." + methodInvocation.getMethod());
Object result=null;
try
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
result=methodInvocation.proceed();
}
finally
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
logger.log(Level.INFO, "method end..." + methodInvocation.getMethod() + " ");
}
return result;
}
}
beans-config.xml
<?
xml version="1.0" encoding="UTF-8"
?>
<!
DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
beans
>
<
bean
id
="logBeforeAdvice"
class
="com.ergal.spring.LogBeforeAdvice"
/>
<
bean
id
="logAfterAdvice"
class
="com.ergal.spring.LogAfterAdvice"
/>
<
bean
id
="helloSpeaker"
class
="com.ergal.spring.HelloSpeaker"
/>
<
bean
id
="logInterceptor"
class
="com.ergal.spring.LogInterceptor"
/>
<
bean
id
="helloProxy"
class
="org.springframework.aop.framework.ProxyFactoryBean"
>
<
property
name
="proxyInterfaces"
>
<
value
>
com.ergal.spring.IHello
</
value
>
</
property
>
<
property
name
="target"
>
<
ref
bean
="helloSpeaker"
/>
</
property
>
<
property
name
="interceptorNames"
>
<
list
>
<
value
>
logInterceptor
</
value
>
</
list
>
</
property
>
</
bean
>
</
beans
>
Throw Advice
在发生异常的时候同志某些服务对象做某些事
例子
IHello.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
interface
IHello
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public void hello(String name) throws Throwable;
}
HelloSpeaker.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
HelloSpeaker
implements
IHello
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public void hello(String name)throws Throwable
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
System.out.println("hello !" + name);
throw new Exception("发生异常");
}
}
SomeThrowAdvice.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
java.lang.reflect.Method;
import
java.util.logging.Level;
import
java.util.logging.Logger;
import
org.springframework.aop.ThrowsAdvice;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
SomeThrowAdvice
implements
ThrowsAdvice
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
private Logger logger=Logger.getLogger(this.getClass().getName());
public void afterThrowing(Method method, Object[] args, Object target, Throwable subclass)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
logger.log(Level.INFO, "Logging that a " + subclass +"Exception was thrown in" + method);
}
}
beans-config.xml
<?
xml version="1.0" encoding="UTF-8"
?>
<!
DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
beans
>
<
bean
id
="someThrowAdvice"
class
="com.ergal.spring.SomeThrowAdvice"
/>
<
bean
id
="helloSpeaker"
class
="com.ergal.spring.HelloSpeaker"
/>
<
bean
id
="helloProxy"
class
="org.springframework.aop.framework.ProxyFactoryBean"
>
<
property
name
="proxyInterfaces"
>
<
value
>
com.ergal.spring.IHello
</
value
>
</
property
>
<
property
name
="target"
>
<
ref
bean
="helloSpeaker"
/>
</
property
>
<
property
name
="interceptorNames"
>
<
list
>
<
value
>
someThrowAdvice
</
value
>
</
list
>
</
property
>
</
bean
>
</
beans
>
SpringDemo.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.support.FileSystemXmlApplicationContext;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
SpringDemo
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public static void main(String[] args)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
ApplicationContext context=new FileSystemXmlApplicationContext("beans-config.xml");
IHello helloproxy=(IHello)context.getBean("helloProxy");
try
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
helloproxy.hello("Rainytooo");
}
catch(Throwable throwable)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
System.err.println(throwable);
}
}
}
结果
hello !Rainytooo
2006-9-30 4:07:47 org.springframework.core.CollectionFactory <clinit>
信息: JDK 1.4+ collections available
2006-9-30 4:07:48 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from file [D:workspacespringdemoeans-config.xml]
2006-9-30 4:07:48 org.springframework.context.support.AbstractRefreshableApplicationContext refreshBeanFactory
信息: Bean factory for application context [org.springframework.context.support.FileSystemXmlApplicationContext;hashCode=8795033]: org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [someThrowAdvice,helloSpeaker,helloProxy]; root of BeanFactory hierarchy
2006-9-30 4:07:48 org.springframework.context.support.AbstractApplicationContext refresh
信息: 3 beans defined in application context [org.springframework.context.support.FileSystemXmlApplicationContext;hashCode=8795033]
2006-9-30 4:07:48 org.springframework.context.support.AbstractApplicationContext initMessageSource
信息: Unable to locate MessageSource with name 'messageSource': using default [org.springframework.context.support.DelegatingMessageSource@1034bb5]
2006-9-30 4:07:48 org.springframework.context.support.AbstractApplicationContext initApplicationEventMulticaster
信息: Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [org.springframework.context.event.SimpleApplicationEventMulticaster@1cfb549]
2006-9-30 4:07:48 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in factory [org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [someThrowAdvice,helloSpeaker,helloProxy]; root of BeanFactory hierarchy]
2006-9-30 4:07:48 org.springframework.aop.framework.DefaultAopProxyFactory <clinit>
信息: CGLIB2 not available: proxyTargetClass feature disabled
2006-9-30 4:07:48 com.ergal.spring.SomeThrowAdvice afterThrowing
信息: Logging that a java.lang.Exception: 发生异常Exception was thrown inpublic abstract void com.ergal.spring.IHello.hello(java.lang.String) throws java.lang.Throwable
java.lang.Exception: 发生异常
Pointcut
定义了Advice的应用时机 在Spring中 使用PointcutAdvisor 将Pointcut和Advice合成为一个对象 Spring内建的Pointcut都有对应的PointcutAdvisor
NameMatchMethodPointcutAdvisor
这是静态的
例子
IHello.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
interface
IHello
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public void helloNewbie(String name);
public void helloMaster(String name);
}
HelloSpeaker.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
HelloSpeaker
implements
IHello
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
public void helloNewbie(String name)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
// TODO Auto-generated method stub
System.out.println("Hello !"+name+" Newbie");
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
public void helloMaster(String name)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
// TODO Auto-generated method stub
System.out.println("Hello !"+name+" Master");
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
LogbeforeAdvice.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
java.lang.reflect.Method;
import
java.util.logging.Level;
import
java.util.logging.Logger;
import
org.springframework.aop.MethodBeforeAdvice;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
LogBeforeAdvice
implements
MethodBeforeAdvice
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
private Logger logger=Logger.getLogger(this.getClass().getName());
public void before(Method method, Object[] args, Object target)throws Throwable
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
logger.log(Level.INFO, "method starts....", method);
}
}
beans-config.xml
<?
xml version="1.0" encoding="UTF-8"
?>
<!
DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
beans
>
<
bean
id
="logBeforeAdvice"
class
="com.ergal.spring.LogBeforeAdvice"
/>
<
bean
id
="helloSpeaker"
class
="com.ergal.spring.HelloSpeaker"
/>
<
bean
id
="helloAdvisor"
class
="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"
>
<
property
name
="mappedName"
>
<
value
>
hello*
</
value
>
</
property
>
<
property
name
="advice"
>
<
ref
bean
="logBeforeAdvice"
/>
</
property
>
</
bean
>
<
bean
id
="helloProxy"
class
="org.springframework.aop.framework.ProxyFactoryBean"
>
<
property
name
="proxyInterfaces"
>
<
value
>
com.ergal.spring.IHello
</
value
>
</
property
>
<
property
name
="target"
>
<
ref
bean
="helloSpeaker"
/>
</
property
>
<
property
name
="interceptorNames"
>
<
list
>
<
value
>
helloAdvisor
</
value
>
</
list
>
</
property
>
</
bean
>
</
beans
>
SPringDemo.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.support.FileSystemXmlApplicationContext;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
SpringDemo
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public static void main(String[] args)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
ApplicationContext context=new FileSystemXmlApplicationContext("beans-config.xml");
IHello helloProxy=(IHello)context.getBean("helloProxy");
helloProxy.helloNewbie("wang");
helloProxy.helloMaster("zhang");
}
}
测试结果
2006-9-30 6:04:49 com.ergal.spring.LogBeforeAdvice before
信息: method starts....
2006-9-30 6:04:49 com.ergal.spring.LogBeforeAdvice before
信息: method starts....
Hello !wang Newbie
Hello !zhang Master
在Eclipse下运行怎么结果不一样
ComtrolFlowPointcut
org.springframework.aop.support.ControlFlowPointcut 是Spring说提供的类 作为判断在方法的执行堆栈中 某个指定类的方法中 是否曾经要求您的目标对象执行某个动作 由于这是在执行过程中才决定是否介入Advice 所以是动态的
例子
Some.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.springframework.beans.BeansException;
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.ApplicationContextAware;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
Some
implements
ApplicationContextAware
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
private IHello helloProxy;
public void setApplicationContext(ApplicationContext context)
throws BeansException
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
// TODO Auto-generated method stub
helloProxy=(IHello)context.getBean("helloProxy");
}
public void helloEveryBody()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
helloProxy.helloNewbie("Wang");
helloProxy.helloMaster("Zhang");
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
SpringDemo.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.support.FileSystemXmlApplicationContext;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
SpringDemo
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public static void main(String[] args)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
ApplicationContext context=new FileSystemXmlApplicationContext("beans-config.xml");
Some some=(Some)context.getBean("some");
//some.helloEveryBody();
System.out.println("Nothing");
}
}
beans-config.xml
<?
xml version="1.0" encoding="UTF-8"
?>
<!
DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
beans
>
<
bean
id
="some"
class
="com.ergal.spring.Some"
/>
<
bean
id
="logBeforeAdvice"
class
="com.ergal.spring.LogBeforeAdvice"
/>
<
bean
id
="helloSpeaker"
class
="com.ergal.spring.HelloSpeaker"
/>
<
bean
id
="helloFlowControlPointcut"
class
="org.springframework.aop.support.ControlFlowPointcut"
>
<
constructor-arg
>
<
value
>
com.ergal.spring.Some
</
value
>
</
constructor-arg
>
</
bean
>
<
bean
id
="helloAdvisor"
class
="org.springframework.aop.support.DefaultPointcutAdvisor"
>
<
property
name
="advice"
>
<
ref
bean
="logBeforeAdvice"
/>
</
property
>
<
property
name
="pointcut"
>
<
ref
bean
="helloFlowControlPointcut"
/>
</
property
>
</
bean
>
<
bean
id
="helloProxy"
class
="org.springframework.aop.framework.ProxyFactoryBean"
>
<
property
name
="proxyInterfaces"
>
<
value
>
com.ergal.spring.IHello
</
value
>
</
property
>
<
property
name
="target"
>
<
ref
bean
="helloSpeaker"
/>
</
property
>
<
property
name
="interceptorNames"
>
<
list
>
<
value
>
helloAdvisor
</
value
>
</
list
>
</
property
>
</
bean
>
</
beans
>
这样在执行方法和不执行方法的时候就有区别了 从而实现了动态的Pointcut
Introduction
追加 可以给现有的类增加方法
修改 从而分离原来的类 不影响(我是这么理解的)
比如这个类IntroductionInterceptor
例子来说明
Some.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
interface
Some
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public void doSome();
}
Someone.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
Someone
implements
Some
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
public void doSome()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
// TODO Auto-generated method stub
System.out.println("原来要做的事情.........");
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
Other.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
interface
Other
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public void doOther();
}
Otherone.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.aopalliance.intercept.MethodInvocation;
import
org.springframework.aop.IntroductionInterceptor;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
Otherone
implements
Other, IntroductionInterceptor
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
public void doOther()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
// TODO Auto-generated method stub
System.out.println("后来添加的事情进来.......");
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
public Object invoke(MethodInvocation arg0) throws Throwable
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
// TODO Auto-generated method stub
if(implementsInterface(arg0.getMethod().getDeclaringClass()))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
return arg0.getMethod().invoke(this, arg0.getArguments());
}
else
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
return arg0.proceed();
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
public boolean implementsInterface(Class arg0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
// TODO Auto-generated method stub
return arg0.isAssignableFrom(Other.class);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
SpringDemo.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.support.FileSystemXmlApplicationContext;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
SpringDemo
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public static void main(String[] args)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
ApplicationContext context=new FileSystemXmlApplicationContext("beans-config.xml");
Some some=(Some)context.getBean("helloProxy");
some.doSome();
((Other)some).doOther();
}
}
beans-config.xml
<?
xml version="1.0" encoding="UTF-8"
?>
<!
DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
beans
>
<
bean
id
="someone"
class
="com.ergal.spring.Someone"
/>
<
bean
id
="otherone"
class
="com.ergal.spring.Otherone"
/>
<
bean
id
="otherAdvice"
class
="org.springframework.aop.support.DefaultIntroductionAdvisor"
>
<
constructor-arg
index
="0"
>
<
ref
bean
="otherone"
/>
</
constructor-arg
>
<
constructor-arg
index
="1"
>
<
value
>
com.ergal.spring.Other
</
value
>
</
constructor-arg
>
</
bean
>
<
bean
id
="helloProxy"
class
="org.springframework.aop.framework.ProxyFactoryBean"
>
<
property
name
="proxyInterfaces"
>
<
value
>
com.ergal.spring.Some
</
value
>
</
property
>
<
property
name
="target"
>
<
ref
bean
="someone"
/>
</
property
>
<
property
name
="interceptorNames"
>
<
list
>
<
value
>
otherAdvice
</
value
>
</
list
>
</
property
>
</
bean
>
</
beans
>
结果
2006-9-30 10:04:30 org.springframework.core.CollectionFactory <clinit>
信息: JDK 1.4+ collections available
2006-9-30 10:04:30 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from file [D:/workspace/springdemo/beans-config.xml]
2006-9-30 10:04:30 org.springframework.context.support.AbstractRefreshableApplicationContext refreshBeanFactory
信息: Bean factory for application context [org.springframework.context.support.FileSystemXmlApplicationContext;hashCode=8795033]: org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [someone,otherone,otherAdvice,helloProxy]; root of BeanFactory hierarchy
2006-9-30 10:04:30 org.springframework.context.support.AbstractApplicationContext refresh
信息: 4 beans defined in application context [org.springframework.context.support.FileSystemXmlApplicationContext;hashCode=8795033]
2006-9-30 10:04:30 org.springframework.context.support.AbstractApplicationContext initMessageSource
信息: Unable to locate MessageSource with name 'messageSource': using default [org.springframework.context.support.DelegatingMessageSource@87816d]
2006-9-30 10:04:30 org.springframework.context.support.AbstractApplicationContext initApplicationEventMulticaster
信息: Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [org.springframework.context.event.SimpleApplicationEventMulticaster@1d9dc39]
2006-9-30 10:04:30 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in factory [org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [someone,otherone,otherAdvice,helloProxy]; root of BeanFactory hierarchy]
2006-9-30 10:04:30 org.springframework.aop.framework.DefaultAopProxyFactory <clinit>
信息: CGLIB2 not available: proxyTargetClass feature disabled
原来要做的事情.........
后来添加的事情进来.......
DelegatingIntroductionInterceptor
在不改变原有对象的状态下给目标对象添加 状态 来实现锁定
例子
Some.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
interface
Some
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public void setSome(String some);
public String getSome();
}
Someone.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
Someone
implements
Some
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
private String some;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
public void setSome(String some)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
// TODO Auto-generated method stub
this.some=some;
}
public String getSome()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
return some;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
ILockable.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
interface
ILockable
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public void lock();
public void unlock();
public boolean isLocked();
}
LockIntroduction.java
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.aopalliance.intercept.MethodInvocation;
import
org.springframework.aop.framework.AopConfigException;
import
org.springframework.aop.support.DelegatingIntroductionInterceptor;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
LockIntroduction
extends
DelegatingIntroductionInterceptor
implements
ILockable
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
private boolean locked;
public Object invoke(MethodInvocation invocation)throws Throwable
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if(isLocked() && invocation.getMethod().getName().indexOf("set")==0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
throw new AopConfigException("物件被锁定...");
}
return super.invoke(invocation);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public boolean isLocked() ...{
// TODO Auto-generated method stub
return locked;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void lock() ...{
// TODO Auto-generated method stub
locked=true;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void unlock() ...{
// TODO Auto-generated method stub
locked=false;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
package
com.ergal.spring;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.support.FileSystemXmlApplicationContext;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
public
class
SpringDemo
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public static void main(String[] args)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
ApplicationContext context=new FileSystemXmlApplicationContext("beans-config.xml");
Some some=(Some)context.getBean("helloProxy");
some.setSome("wang");
System.out.println(some.getSome());
try
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
((ILockable)some).lock();
some.setSome("zhang");
System.out.println(some.getSome());
}
catch(Throwable e)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
e.printStackTrace();
}
((ILockable)some).unlock();
some.setSome("zhang");
System.out.println(some.getSome());
}
}
beans-config.xml
<?
xml version="1.0" encoding="UTF-8"
?>
<!
DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
beans
>
<
bean
id
="someone"
class
="com.ergal.spring.Someone"
/>
<
bean
id
="lockIntroduction"
class
="com.ergal.spring.LockIntroduction"
/>
<
bean
id
="lockAdvisor"
class
="org.springframework.aop.support.DefaultIntroductionAdvisor"
>
<
constructor-arg
index
="0"
>
<
ref
bean
="lockIntroduction"
/>
</
constructor-arg
>
<
constructor-arg
index
="1"
>
<
value
>
com.ergal.spring.ILockable
</
value
>
</
constructor-arg
>
</
bean
>
<
bean
id
="helloProxy"
class
="org.springframework.aop.framework.ProxyFactoryBean"
>
<
property
name
="proxyInterfaces"
>
<
value
>
com.ergal.spring.Some
</
value
>
</
property
>
<
property
name
="target"
>
<
ref
bean
="someone"
/>
</
property
>
<
property
name
="interceptorNames"
>
<
list
>
<
value
>
lockAdvisor
</
value
>
</
list
>
</
property
>
</
bean
>
</
beans
>
结果
2006-9-30 10:47:33 org.springframework.core.CollectionFactory <clinit>
信息: JDK 1.4+ collections available
2006-9-30 10:47:34 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from file [D:workspacespringdemoeans-config.xml]
2006-9-30 10:47:34 org.springframework.context.support.AbstractRefreshableApplicationContext refreshBeanFactory
信息: Bean factory for application context [org.springframework.context.support.FileSystemXmlApplicationContext;hashCode=8795033]: org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [someone,lockIntroduction,lockAdvisor,helloProxy]; root of BeanFactory hierarchy
2006-9-30 10:47:34 org.springframework.context.support.AbstractApplicationContext refresh
信息: 4 beans defined in application context [org.springframework.context.support.FileSystemXmlApplicationContext;hashCode=8795033]
2006-9-30 10:47:34 org.springframework.context.support.AbstractApplicationContext initMessageSource
信息: Unable to locate MessageSource with name 'messageSource': using default [org.springframework.context.support.DelegatingMessageSource@1d9dc39]
2006-9-30 10:47:34 org.springframework.context.support.AbstractApplicationContext initApplicationEventMulticaster
信息: Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [org.springframework.context.event.SimpleApplicationEventMulticaster@111a3ac]
2006-9-30 10:47:34 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in factory [org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [someone,lockIntroduction,lockAdvisor,helloProxy]; root of BeanFactory hierarchy]
2006-9-30 10:47:34 org.springframework.aop.framework.DefaultAopProxyFactory <clinit>
信息: CGLIB2 not available: proxyTargetClass feature disabled
org.springframework.aop.framework.AopConfigException: 物件被锁定...
at com.ergal.spring.LockIntroduction.invoke(LockIntroduction.java:15)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
at $Proxy0.setSome(Unknown Source)
at com.ergal.spring.SpringDemo.main(SpringDemo.java:21)
wang
zhang
自动代理
怕怕