[TOC]java
因为公司有本身的框架,整个架构跟
Spring
几乎沾不上边,在业余时间对Spring
框架的学习,最近开始学习切面编程**“Spring AOP”
**,而且在博文中记录一下,以便往后快速上手git
这一章先了解一下什么是AOP,以及写一个简单的例子github
aop叫aspect oriented program,面向切面的编程。那什么是面向切面编程,切面就是可插可拔,俗一点说就是想要就要,想不要就不要。直接看看下图理解一下spring
咱们在编程的时候不少重复的代码如:编程
当项目开发到必定程度的时候,咱们若是忽然要说加上这么多东西,那多要命啊。那么这个时候咱们能够考虑加入AOP了架构
有人问,若是不用spring,那还有其余框架吗?那是必须的 笔者了解到的能够作到的有下面几个app
该例子是从spring官网下拿下来进行测试的,笔者尝试了能够成功运行框架
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--支持扫描包--> <context:component-scan base-package="com.carl.spring"/> <!--支持注解--> <context:annotation-config/> <!--其余配置文件--> <import resource="services.xml"></import> </beans>
spring 入口配置文件eclipse
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--aop start--> <bean id="createUserProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="com.carl.spring.hello.aop.ISampleCreateUser"/> <!-- Use inner bean, not local reference to target --> <property name="target" ref="sampleCreateUser"> </property> <property name="interceptorNames"> <list> <value>debugInterceptor</value> </list> </property> </bean> <!--aop end--> </beans>
该配置是AOP的一个代理配置,获取对象的时候,直接获取
createUserProxy
就能够获取target
执行的代理对象,(由于ProxyFactoryBean实现了FactoryBean,能够直接获取对应的对象);interceptorNames
就是切面的对象了Advice/Advisor/Interceptor
ide
package com.carl.spring.hello.aop; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.stereotype.Component; /** * @author Carl * @date 2016/9/11 */ @Component("debugInterceptor") public class DebugInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("Before: invocation=[" + methodInvocation + "]"); Object rval = methodInvocation.proceed(); System.out.println("Invocation returned"); return rval; } }
methodInvocation.proceed();
为执行代理方法,在执行代理方法前和执行方法后,执行了一些系统输出
package com.carl.spring.hello.aop; /** * @author Carl * @date 2016/9/11 */ public interface ISampleCreateUser { String create(); }
这里只作一个接口的定义
package com.carl.spring.hello.aop; import org.springframework.stereotype.Service; /** * @author Carl * @date 2016/9/11 */ @Service("sampleCreateUser") public class SampleCreateUserImpl implements ISampleCreateUser { @Override public String create() { System.out.println("invoking SampleCreateUserImpl.create()"); return "return res for SampleCreateUserImpl.create()"; } }
注意,这里有一个注解
@Service("sampleCreateUser")
,不然在service.xml获取不了代理对象
package com.carl.spring.hello.bean; import org.junit.Before; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author Carl * @date 2016/8/28 */ public abstract class BaseTest { protected ApplicationContext context; @Before public void setUp() throws Exception { context = new ClassPathXmlApplicationContext(new String[] {"application-context.xml"}); } }
package com.carl.spring.hello.aop; import com.carl.spring.hello.bean.BaseTest; import org.junit.Test; import static org.junit.Assert.*; /** * Created by Administrator on 2016/9/11. */ public class ISampleCreateUserTest extends BaseTest { @Test public void create() throws Exception { ISampleCreateUser createUser = context.getBean("createUserProxy", ISampleCreateUser.class); assertNotNull(createUser); String res = createUser.create(); assertEquals("return res for SampleCreateUserImpl.create()", res); System.out.println(res); } }
Junit的真实测试类
该结果是从控制台中直接输出
Before: invocation=[ReflectiveMethodInvocation: public abstract java.lang.String com.carl.spring.hello.aop.ISampleCreateUser.create(); target is of class [com.carl.spring.hello.aop.SampleCreateUserImpl]] invoking SampleCreateUserImpl.create() Invocation returned return res for SampleCreateUserImpl.create()
最终仍是实现了切面,可插拔的东西,可是对象必须交给spring进行代理
methodInvocation.proceed()
前置执行/后置执行/异常时执行/先后都执行
**这上面的内容spring均可以很好的解决,在后面的博文中会记下来