Spring提供了结合了java自带的代理方式和Cglib的代理方式,提供了多种构造代理的入口。
package org.antstudio; public interface Animal { public String say(); public String name(); }
package org.antstudio; import org.springframework.stereotype.Component; @Component public class Cat implements Animal{ @Override public String say() { System.out.println("miao."); return "Miao"; } @Override public String name() { return "Cat"; } }
package org.antstudio; import org.springframework.stereotype.Component; /** * 这里不实现Animal接口,以测试无接口时的代理 */ @Component public class Dog { public String say(){ System.out.println("Wang."); return "Wang"; } public String name(){ return "Dog"; } }
package org.antstudio.org.antstudio.proxy; import org.springframework.aop.MethodBeforeAdvice; import org.springframework.stereotype.Component; import java.lang.reflect.Method; @Component public class AnimalBeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("Before execute "+ method.getName()); } }
<bean id="personProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="interfaces"> <list> <value>org.antstudio.Animal</value> </list> </property> <property name="interceptorNames"> <list> <value>animalBeforeAdvice</value> </list> </property> <property name="target"> <ref bean="cat"></ref> </property> </bean>
<bean id="dogProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="interceptorNames"> <list> <value>animalBeforeAdvice</value> </list> </property> <property name="target"> <ref bean="dog"></ref> </property> </bean>
package org.antstudio; import junit.framework.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:spring-config.xml") public class ProxyFactoryBeanTests { @Autowired private BeanFactory beanFactory; @Test public void testCatProxyFactory() { Animal p = (Animal)beanFactory.getBean("catProxy") ; System.out.println(p.getClass());//class com.sun.proxy.$Proxy11 Assert.assertEquals(p.say(), "Miao"); } @Test public void testDogProxyFactory() { Dog d = (Dog)beanFactory.getBean("dogProxy") ; System.out.println(d.getClass());//class org.antstudio.Dog$$EnhancerByCGLIB$$d23a9052 Assert.assertEquals(d.say(), "Wang"); } }
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames"> <list> <value>cat*</value> <value>dog*</value> </list> </property> <property name="interceptorNames"> <list> <value>animalBeforeAdvice</value> </list> </property> </bean>
package org.antstudio; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.beans.factory.BeanFactory; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource; /** * @author Gavin */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:spring-config.xml") public class BeanNameAutoProxyCreatoryTests { @Resource private BeanFactory beanFactory; @Resource private Dog dog; @Test public void testCat(){ Animal cat = (Animal) beanFactory.getBean("cat"); cat.say(); cat.name(); } @Test public void testDog(){ dog.say(); } }注意:上例中,如果对于Cat采用Dog的注入方式,即:
@Resource private Cat cat;
<bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="patterns"> <list> <value>.*say</value> </list> </property> <property name="advice"> <ref bean="animalAfterAdvice"></ref> </property> </bean>