Spring基本理解,如IOC、AOP等

Spring中AOP代理(一个Bean)由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。Spring创建代理的规则为:

1、默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了

2、当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可强制使用CGLIB


IOC(反转控制)可以定义为:由IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

Spring中,最基本的IOC容器接口是BeanFactory ,该接口为具体的IOC容器的实现作了最基本的功能规定

DI-Dependency Injection,即依赖注入,组件之间依赖关系由容器在运行期决定。


AOP(Aspect Orient Programming),我们一般称为面向方面(切面)编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理、日志、缓存等等。AOP实现的关键在于AOP框架自动创建的AOP代理,AOP代理主要分为静态代理和动态代理,静态代理的代表为AspectJ;而动态代理则以Spring AOP为代表。

参见 http://www.cnblogs.com/xrq730/p/4919025.html (非常好)

Spring默认以aspect的定义顺序作为织入顺序,但aspect里面有一个order属性,order属性的数字就是横切关注点的顺序


AOP核心概念

1、横切关注点-------------------------对应一个类(想要把这个类的方法(如日志)加到其他类的方法上的这个类)

对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点

2、切面(aspect)---------------------对应一个类

类是对物体特征的抽象,切面就是对横切关注点的抽象

3、连接点(joinpoint)

被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器

4、切入点(pointcut)------------------定义连接点

对连接点进行拦截的定义

5、通知(advice)-----------------------对应类里的方法

所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类

6、目标对象

代理的目标对象

7、织入(weave)

将切面应用到目标对象并导致代理对象创建的过程

8、引入(introduction)

在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段


    <!-- AOP方式事务配置 -->
    <aop:aspectj-autoproxy proxy-target-class="true" />
    <!-- 为业务逻辑层的方法解析@DataSource注解 为当前线程的routeholder注入数据源key -->
    <bean id="dataSourceAspect" class="com.xxx.util.DataSourceAspect" />
    <aop:config proxy-target-class="true">
        <aop:aspect id="dataSourceAspect" ref="dataSourceAspect"
            order="1">
            <aop:pointcut id="tx" expression="execution(* com.xxx..*.*(..)) " />
            <aop:before pointcut-ref="tx" method="before" />
        </aop:aspect>

    </aop:config>

<!-- 配置通知 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- 增删改加入事物控制 -->
            <tx:method name="delete*" propagation="REQUIRED" read-only="false"
                rollback-for="java.lang.Exception" />
            <tx:method name="insert*" propagation="REQUIRED" read-only="false"
                rollback-for="java.lang.Exception" />
            <tx:method name="update*" propagation="REQUIRED" read-only="false"
                rollback-for="java.lang.Exception" />
            <tx:method name="save*" propagation="REQUIRED" read-only="false"
                rollback-for="java.lang.Exception" />

            <!-- 查询方法(只读)不用事物控制 -->
            <tx:method name="find*" propagation="SUPPORTS" read-only="true" />
            <tx:method name="get*" propagation="SUPPORTS" read-only="true" />
            <tx:method name="select*" propagation="SUPPORTS" read-only="true" />
        </tx:attributes>
    </tx:advice>


public class DataSourceAspect
{
    /**
     * 在dao层方法之前,获取datasource对象之前,在切面中指定当前线程数据源路由的key
     */
    public void before(JoinPoint point)
    {
        Object target = point.getTarget();
        System.out.println(target.toString());
        String method = point.getSignature().getName();
        System.out.println(method);
        Class<?>[] classz = target.getClass().getInterfaces();
        Class<?>[] parameterTypes = ((MethodSignature) point.getSignature()).getMethod().getParameterTypes();
        try
        {
            Method m = classz[0].getMethod(method, parameterTypes);
            System.out.println(m.getName());
            if (m != null && m.isAnnotationPresent(DataSource.class))
            {
                DataSource data = m.getAnnotation(DataSource.class);
                System.out.println("用户选择数据库库类型:" + data.value());
                HandleDataSource.putDataSource(data.value());
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值