Spring三大思想理解

Spring三大思想:IOC(反转控制)、DI(依赖注入)、AOP(面向切面编程)

  • Spring的出现是为了让开发回到bean本身,脱离繁杂的设计模式代码。

1、IOC(反转控制)

IOC(反转控制)创立是Spring的主要思想,意在实现模块间解耦,主要功能是实现代替java设计模式中的工厂模式,使类的引用实例化不需要导入其他模块类的路径。Spring会维护一个IOC容器,以Map的形式存储id和包类路径,将有可能被引用的类创建在IOC容器中,然后需要比如A类中引用B类对象进行实例化,就可以在IOC容器中取得B类的实例化,这里多例和单例问题可以选择,默认单例。
Spring提供两种方式实现:

  • 标签方式创建
<bean id = "a" class="com.xx.xx.A"></bean>
  • 注解方式创建:需要在xml配置文件中导入注解方式的依赖和需要扫描的包。当然可以使用java配置。
    注解:@Component @Controller @Service @Repository
/**
*@Component  @Controller @Service @Repository
*上门有四种实现注解方式创建,Component通用,Controller控制层,Service业**务层,Repository持久层。 工业流程一般这样定义,提高可读性。
*/
@Component
public class A{
........
}

2、DI(依赖注入)

DI(依赖注入) 一般和IOC共用,所以导入概念模糊。DI主要功能是将IOC容器的实例对象注入到某个需要使用改实例的另一个实例,这就会有个问题就是谁依赖了谁?谁注入了谁。如A类要被B类引用,这里就需要将IOC容器实现的A类实例注入到B类实例中,B类实例依赖于IOC容器的A类实例。
实现方式:

  • 标签方式创建
<bean id = "a" class="com.xx.xx.A"></bean>
<bean id = "b" class="com.xx.xx.B">
<--! name属性是第一个在B类的属性,属性名为a,ref属性是对a类实例化的id属性 -->
<property name = "a" ref="a" />
</bean>
  • 注解实现方式
    注解:Autowired
@Component
public class B{
/**
*这里A类的创建不用导包,且已经注入,而且这里A的对象名a是可以任意取的,
*只要在IOC容器中有唯一创建的A的实例,若A在IOC容器有多个实例则另说,这里不做
*展开。
*/
 @Autowried
 private A a;
}

3、AOP(面向切面编程)

AOP(面向切面编程)可以比喻为拦截器,主要是功能是实现动态代理设计模式。可以实现事务管理,日志跟踪动态过程等等。比如要实现银行账户转账逻辑,需要保护事务的一致性,A账户转账给B账户为,A账户减钱为P1事务,B账户加钱为P2事务,要保证事务的一致性不能出现A账户减钱,B账户却没有加钱的情况。要实现上面的功能,使用AOP设置:

  • 前置操作(通知)
  • 后置操作(通知)
  • 异常操作(通知)
  • 最后操作(通知)
    其中前置操作和最好操作在事务操作的任意情况下都会做,但是后置操作只会在P1 P2事务都完成的情况下才能执行后置操作,异常操作需要设置回滚,在P1 P2任意一个事务未能完成出现异常情况下,将已经执行了的操作都进行回滚。
    实现方式:
  • 标签方式实现
 <!-- aop配置-->
    <aop:config >
        <aop:aspect id="asptest" ref="txManager">
            <!-- 配置事务管理切入面与切入点的关联 -->
            <aop:before method="beginTransaction"  pointcut="execution(* com.itheima.service.impl.AccountServiceImpl.transfer(..))"></aop:before>

            <aop:after-returning method="commit" pointcut="execution(* com.itheima.service.impl.AccountServiceImpl.transfer(..))"></aop:after-returning>

            <aop:after-throwing method="rollback"  pointcut="execution(* com.itheima.service.impl.AccountServiceImpl.transfer(..))"></aop:after-throwing>

            <aop:after method="release"  pointcut="execution(* com.itheima.service.impl.AccountServiceImpl.transfer(..))"></aop:after>
        </aop:aspect>
    </aop:config>
  • 注解实现
    注解:@Transactional
//需要的是读写型事务配置
    @Transactional(propagation= Propagation.REQUIRED,readOnly=false)
    public void transfer(String sourceName, String targetName, Float money) {
        System.out.println("transfer....");
            //2.1根据名称查询转出账户
            Account source = accountDao.findAccountByName(sourceName);
            //2.2根据名称查询转入账户
            Account target = accountDao.findAccountByName(targetName);
            //2.3转出账户减钱
            source.setMoney(source.getMoney()-money);
            //2.4转入账户加钱
            target.setMoney(target.getMoney()+money);
            //2.5更新转出账户
            accountDao.updateAccount(source);

            int i=1/0;

            //2.6更新转入账户
            accountDao.updateAccount(target);
    }

注意点

  • aop的环绕通知的两种实现方式得到的事务控制逻辑不一样:
    标签方式的环绕通知与自己设计的四个通知逻辑一致,注解方式的环绕通知再逻辑会先执行最后通知再执行后置通知。
  • 以上对Spring的很浅略学习掌握输出,Spring框架作为一个成熟且流行的框架,值得且需要我们去学习。
发布了34 篇原创文章 · 获赞 1 · 访问量 538

猜你喜欢

转载自blog.csdn.net/weixin_44185736/article/details/104877131