Spring的控制反转和依赖注入

 

面向切面编程,横向编程思想,区别于传统的纵向提取思想,可以用代理思想理解。

底层实现原理:动态代理。jdk动态代理(只能代理实现了接口的类)和Cglib动态代理(可代理没实现接口的类,生成子类对象)。具体选择哪种代理模式,Spring会根据是否实现接口来选择,底层自动切换。

作用:对程序进行增强。在不修改源代码的情况下,AOP可以进行权限校验、日志记录、性能监控、事务控制。

AOP思想是由AOP联盟提出的,Spring是最好的实现着,Spring自己的AOP过于繁琐,引入了Aspectj的AOP作为自己的AOP(Spring有两套AOP开发方式,基于Aspectj仍在使用->XML配置)。

AOP开发中的相关术语

JoinPoint(连接点):可以被拦截的点。(可以被增强的点)。

PointCut(切入点):真正被拦截到的点。(实际被增强的点)。

Advice(通知/增强):(对某个方法增强,增强的方法称为通知)。通知:前置通知(权限校验)/后置通知(日志记录)/环绕通知(性能监控)。

Introduction(引介):(也是一种增强,对某个类增强)。

Target:被增强的对象。

Waving(织入):将Advice 应用到 Target 的过程。织入增强后会产生代理。

Aspect(切面):多个 通知 和 多个切入点 的组合。

AOP编程入门

      AOP底层基于动态代理,Spring具体使用那种代理模式根据我们定义的继承实现关系决定。Spring框架使用AOP基于XML配置的编程思路如下:

首先创建接口&实现类(或创建实体类),再applicationContext.xml中引入

创建ProductDao

package com.aloha.proxy;

public interface ProductDao {
    void add();
    void delete();
    void change();
    void find();
}

创建ProductDaoImpl

package com.aloha.proxy;

public class ProductDaoImpl implements ProductDao {
    @Override
    public void add() {
        System.out.println("add");
    }

    @Override
    public void delete() {
        System.out.println("delete");
    }

    @Override
    public void change() {
        System.out.println("change");
    }

    @Override
    public void find() {
        System.out.println("find");
    }
}

创建Aspect类以及Advice

package com.aloha.proxy;

/**
 * 切面类:放的是切入点&通知的组合
 */
public class MyAspectXML {
    public void checkPri(){
        System.out.println("权限校验");
    }
    public void logging(){
        System.out.println("日志记录");
    }
}

引入bean对象,配置切面,切入点,前向切入

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 配置目标对象:被增强的对象-->
    <bean id="productDao" class="com.aloha.proxy.ProductDaoImpl" />

    <!-- 将切面类交给Spring管理 -->
    <bean id="myAspect" class="com.aloha.proxy.MyAspectXML" />

    <!-- 通过aop配置完成对目标类产生代理 -->
    <aop:config>
        <!-- aop切入点的id随便写,expression:表达式配置哪些类的那些方法需要被增强
            *    任意返回值
            ..   任意参数
        -->
        <aop:pointcut id="pointcut1" expression="execution(* com.aloha.proxy.ProductDaoImpl.add(..))" />
        <!-- 配置切面 -->
        <aop:aspect ref="myAspect">
            <aop:before method="checkPri" pointcut-ref="pointcut1" />
        </aop:aspect>
    </aop:config>


</beans>

创建Spring测试类,测试:

package com.aloha.proxy;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringJunit {
    @Resource(name="productDao")
    private ProductDao productDao;

    @Test
    public void test(){
        productDao.add();
        productDao.change();
        productDao.delete();
        productDao.find();
    }
}

 

测试结果:

可以看到我们在添加用户的方法前向切入一个权限校验的方法,通过Spring的aop实现增强代码量、耦合度都大大降低!

AOP通知类型 

以下几类通知来自顾名思义:

前置通知:在目标方法执行之前的操作。

后置通知:在目标方法执行之后的操作。

环绕通知:在目标方法执行之前和之后的操作(事务执行)。

异常抛出通知:在程序出现异常的时候执行的操作(事务管理使用-回滚)。

最终通知:无论代码是否有异常,这里的一定会执行。

 


控制反转(Inversion of Control)

对象的生命周期不再由代码控制,而是交给spring管理。

BeanFactoryPostProcessor.java  bean解析后实例化前的处理;

BeanDefinitionRegistryPostProcessor.java  继承了上面的接口,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值