spring 学习 AOP和IOC

时间:2021-09-16 22:41:32

自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