spring 学习 AOP和IOC
自11开始接触三大框架,至今已俞5载,
当时风光无限的ssh,现在还在被广泛使用,并有扩大之势的只有spring了
spring主要特性,是广为使用的AOP(面向切面)和IOC(控制反转)
1.其中,IOC(控制反转)也叫依赖注入,使用最是广泛
基本概念是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器 (在 Spring 框架中是 IOC 容器) 负责将这些联系在一起。
就是通过在代码中大量使用接口,并为所有参数编写get,set方法,然后在xml中配置实现类,将具体的实现或参数值注入,以解决代码耦合度过高的问题
常用的方法有2个:
1.通过xml得到
beanFactory BeanFactory factory = new XMLBeanFactory(new FileInputSteam("mybean.xml"));
2.通过beanFactory获取xml中配置的对象
MyBean mybean = (MyBean) factory.getBean("mybean"); xml 实例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="createCreditCard" -->define createCreditCard definition
class="springexample.creditcardaccount.CreateCreditCardAccount">
<property name="creditRatingInterface">-- 参数名称
<ref bean="creditRating" /> -- 注入的bean名称
</property>
</bean>
<bean id="creditLinking" class="springexample.creditlinking.CreditLinking">
<property name="url"> --参数名称
<value>http://localhost/creditLinkService</value> --参数值
</property>
</bean>
<bean id="creditRating" class="springexample.creditrating.CreditRating"> -- bean的实现
</bean>
</beans>
2. AOP是一种编程技术,它允许程序员对横切关注点或横切典型的职责分界线的行为(例如日志和事务管理)进行模块化。AOP 的核心构造是方面,它将那些影响多个类的行为封装到可重用的模块中。 AOP 方式中,可以反过来将日志服务模块化,并以声明的方式将它们应用到需要日志的组件上。当然,优势就是 Java 类不需要知道日志服务的存在,也不需要考虑相关的代码。所以,用 Spring AOP 编写的应用程序代码是松散耦合的。
spring中,我们可以通过配置,或者注解的方式,将特定的方法置于系统的中的某一个方法调用位置之前或之后执行 这样的处理,可以将切面处理的操作独立出来,并可以动态的放置到系统执行的任意位置
Spring提供了4种实现AOP的方式:
1.经典的基于代理的AOP
2.@AspectJ注解驱动的切面
3.纯POJO切面
4.注入式AspectJ切面
Spring支持五种类型的通知:
Before(前) org.apringframework.aop.MethodBeforeAdvice
After-returning(返回后) org.springframework.aop.AfterReturningAdvice
After-throwing(抛出后) org.springframework.aop.ThrowsAdvice
Arround(周围) org.aopaliance.intercept.MethodInterceptor
Introduction(引入) org.springframework.aop.IntroductionIntercept
周围通知,他是由AOP Alliance中的接口定义的而非Spring,周围通知相当于前通知、返回后通知、抛出后通知的结合
1.注入式AspectJ切面xml实例:
<aop:advisor> 定义一个AOP通知者
<aop:after> 后通知
<aop:after-returning> 返回后通知
<aop:after-throwing> 抛出后通知
<aop:around> 周围通知
<aop:aspect>定义一个切面
<aop:before>前通知
<aop:config>顶级配置元素,类似于<beans>这种东西
<aop:pointcut>定义一个切点
我们用AOP标签来实现睡觉这个过程:
代码不变,只是修改配置文件,加入AOP配置即可:
<aop:config>
<aop:aspect ref="sleepHelper">
<aop:before method="beforeSleep" pointcut="execution(* *.sleep(..))"/>
<aop:after method="afterSleep" pointcut="execution(* *.sleep(..))"/>
</aop:aspect>
</aop:config>
2. @AspectJ注解驱动的切面:
package test.mine.spring.bean;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class SleepHelper {
public SleepHelper(){
}
@Pointcut("execution(* *.sleep())")
public void sleeppoint(){}
@Before("sleeppoint()")
public void beforeSleep(){
System.out.println("睡觉前要脱衣服!");
}
@AfterReturning("sleeppoint()")
public void afterSleep(){
System.out.println("睡醒了要穿衣服!");
}
}
用@Aspect的注解来标识切面,注意不要把它漏了,否则Spring创建代理的时候会找不到它,@Pointcut注解指定了切点,@Before和@AfterReturning指定了运行时的通知,注
意的是要在注解中传入切点的名称
然后我们在Spring配置文件上下点功夫,首先是增加AOP的XML命名空间和声明相关schema
命名空间:
xmlns:aop="http://www.springframework.org/schema/aop"
schema声明:
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
然后加上这个标签:
<aop:aspectj-autoproxy/> 有了这个Spring就能够自动扫描被@Aspect标注的切面了
参考:
http://www.ibm.com/developerworks/cn/java/wa-spring1/
http://blog.csdn.net/udbnny/article/details/5870076