Spring Action 笔记(一) 初识Spring

前言

决定写博客,是受了《软技能-代码之外的生存之道》的启发,深知写博客利人利已的好处。

本人之前主要使用的语言并不是java,而是c#,也不是因为想转java而来学习Spring。我认为学习一种框架,不光知道如何使用框架,更重要的是理解框架背后的思想,而这个思想是不受语言限制的。在读了《Spring Action》第一章后,收获很多,也理解了之前一直模糊的一些思想,可以说收获很大,我会坚持这个博客系列,将我所收获的分享出来。下面切入正题。

Spring使命

简化java开发是Spring框架的终极目标,看似简单的几个字,实现起来并不简单,Spring一举颠覆java之前的众多框架,划出一道清新亮丽的风景线。Spring从以下几个方面做了努力使代码更简洁:

  • 激发POJO的潜能,不侵入代码。
  • 通过依赖注入和面向接口实现松耦合
  • 基于切面和惯例进行声明式编程
  • 通过切面和模板减少样板式代码

激发POJO的潜能,不侵入代码。

    之前很多框架都要求使用者继承框架接口或类,使得开发者需要更多的代码来适配框架。Spring可以让开发者只关注业务本身,POJO(Plain Ordinary Java Object)是一个简单的java类,无需为适配框架来写过多的不需要的代码。之下是两个例子:

程序1:EJB2.1 强迫实现你根本不需要的方法

public class HelloWorldBean implements SessionBean {
    public void ejbActivate(){}  // 业务无关的代码
    public void ejbPassivate(){}
    public void ejbRemove(){}
    public void setSessionContext(SessionContext ctx){}
    public void ejbCreate(){}

    public String sayHello() {
        return "Hello World";
    }
}

程序2:Spring简洁的代码

public class HelloWorldBean {
    public String sayHello() {
        return "Hello World";
    }
}

通过依赖注入和面向接口实现松耦合

要理解理解依赖注入,首先搞清楚面向接口编程和面向实现编程的区别。

下面是一个简单的例子,面向接口编程的汽车类(CarA)依赖的是具有跑(Run)功能的轮子(IWheel),只要符合接口的任何厂商的轮子都能装入汽车A,以后想更换轮子,不需要重新来修改汽车架构。而面向实现编程的汽车B(CarB)依赖特定的轮子实现(WhellA),若以后出来更先进的轮子,汽车B也只能相望,除非重新改造自己。所以面向接口编程使得类之间是松耦合的。

程序3:面向接口编程和面向实现编程比较

// 面向接口编程
public class CarA{
    Iwheel whell;  
    
    public Run(){
        whell.Run();
    }
}

// 面向实现编程
public class CarB{
    WhellA whell;  

    public Run(){
        whell.Run();
    }
}

那么依赖注入和面向接口编程是什么关系呢。上例中的汽车A的轮子从何而来?如果是汽车内部new出来,还是依赖了具体实现类,以后换个轮子仍然要修改汽车类,下面的例子,汽车A依赖的轮子由构造函数注入进来,这样把具体使用哪种轮子交给汽车的装配者,汽车框架的制造者不关心轮子选用何种,从何而来,只知道轮子能实现自己想要的Run功能就够了。这样汽车装配者可以根据自己的喜好装出各种汽车(跑车、普通汽车、越野车),所以依赖注入是面向接口编程的一种实现方式。依赖注入除了构造函数注入,还会有其他的注入方式,会在后面的博客中一一解释,这里只需了解依赖注入的思想就够了。

// 面向接口编程
public class Car{
    Iwheel whell;

    public Car(Iwhell whellA){ // 构造函数依赖注入
        this.whell= whellA;
    }

    public Run(){
        whell.Run();
    }
}

基于切面和惯例进行声明式编程

依赖注入让相互协作的软件组件保持松散耦合,而AOP编程允许你把遍布应用各处的功能分离出来形成可重用的组件。哪些功能是遍布应用各处的?比如日志功能,权限功能等,这些功能被称为切面功能,因为他们横切各个业务模块。

相信很多人都看到过一个业务模块被淹没在日志、权限控制、事务这些跟业务逻辑无关的代码中的情况,即使这些功能已经很好的封装,但调用代码还是嵌在了业务逻辑代码中。AOP不但很好地将公共功能封装成组件,还使这些公共功能不会嵌在业务逻辑代码中,使得POJO更简单。如何使得切面功能代码不侵入业务代码中却能实现切面功能呢,Spring采用的是配置的方式,在需要的地方配置需要的切面功能。 比较下面两份代码,你可以很明显的看到切面编程使得POJO非常简洁,只关注业务逻辑,不关心切入功能,使得切面功能和业务模块耦合的更松散。

// 没有使用AOP,依赖日志接口,日志代码侵入业务逻辑
public class Car{
    Iwheel whell;
    ILog log;

    public Run(){
        log.info("before Run");
        whell.Run();
        log.info("after Run");
    }
}

// 使用AOP,POJO根本不知道有日志,日志是否需要和使用何种日志交给使用者,POJO只关心业务逻辑
public class Car{
    Iwheel whell;

    public Run(){
        whell.Run();
    }
}

通过切面和模板减少样板式代码

相信大家有过这种经历,在编写某些代码的时候,感觉跟别的代码很相似,比如数据库代码,或者远程调用,或socket。先连接,后处理业务,然后关闭,还要catch exception等一系列重复性的代码,看下面这个例子,业务代码被样板代码淹没了。

Connection con = null;
        try {
            con = DriverManager.getConnection(dbUrl1, dbUserName, dbPassword);
            var stmt = con.prepareStatement("select * from users");  // 真正的业务代码只有这一行
            var rs = stmt.executeQuery();
            System.out.println("获取数据库连接成功!");
            System.out.println("进行数据库操作!");
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("获取数据库连接失败!");
        }finally{
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
Spring旨在通过模板封装来消除样板式代码,使用jdbcTemplate,样板代码消除了,只需要关心业务逻辑。
jdbcTemplate.queryForObject(
        "select * from users",  // 查询语句
        new RowMapper<User>{} // 结果映射
  )

Bean容器

在spring中,POJO只关心自己的业务逻辑,不关心依赖的创建,实现。那有谁复杂依赖的创建,谁负责依赖的生命周期呢,那就是Bean容器。Bean容器装载所有的Bean(POJO类实例),通过注入bean来组装复杂bean。

 

Bean在容器中有一系列的生命周期节点,Bean开发者可以定义节点的钩子函数来定制Bean,比如销毁的时候,同时释放一些资源。

  • Bean的建立, 由BeanFactory读取Bean定义文件,并生成各个实例
  • Setter注入,执行Bean的属性依赖注入
  • BeanNameAware的setBeanName(), 如果实现该接口,则执行其setBeanName方法
  • BeanFactoryAware的setBeanFactory(),如果实现该接口,则执行其setBeanFactory方法
  • BeanPostProcessor的processBeforeInitialization(),如果有关联的processor,则在Bean初始化之前都会执行这个实例的processBeforeInitialization()方法
  • InitializingBean的afterPropertiesSet(),如果实现了该接口,则执行其afterPropertiesSet()方法
  • Bean定义文件中定义init-method
  • BeanPostProcessors的processAfterInitialization(),如果有关联的processor,则在Bean初始化之前都会执行这个实例的processAfterInitialization()方法
  • DisposableBean的destroy(),在容器关闭时,如果Bean类实现了该接口,则执行它的destroy()方法
  • Bean定义文件中定义destroy-method,在容器关闭时,可以在Bean定义文件中使用“destory-method”定义的

Spring模块

Spring框架由几个不同的模块组成,为开发企业级应用提供了所需的一切,下面是模块的概览图,会在后面的博客中详细介绍各个模块,这里只需要了解Spring的模块组成和各模块的功能就够了。


总结

以上是spring action第一章的总结,主要理解Spring的目标以及通过哪些手段来实现这些目标。相信你对Spring已经有了大概了解。后续博客将对Spring进行全面详细介绍。



  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 第一部分spring的核心 第1章开始spring之旅 1.1spring是什么 1.2开始spring之旅 1.3理解依赖注入 1.3.1依赖注入 1.3.2di应用 1.3.3企业级应用中的依赖注入 1.4应用aop 1.4.1aop介绍 1.4.2aop使用 1.5小结 第2章基本bean装配 2.1容纳你的bean 2.1.1beanfactory介绍 2.1.2使用应用上下文 2.1.3bean的生命 2.2创建bean 2.2.1声明一个简单的bean 2.2.2通过构造函数注入 2.3注入bean属性 2.3.1注入简单的数值 2.3.2使用其他的bean 2.3.3装配集合 2.3.4装配空值 2.4自动装配 2.4.1四种自动装配类型 2.4.2混合使用自动和手动装配 2.4.3何时采用自动装配 2.5控制bean创建 2.5.1bean范围化 2.5.2利用工厂方法来创建bean 2.5.3初始化和销毁bean 2.6小结 第3章高级bean装配 3.1声明父bean和子bean 3.1.1抽象基bean类型 3.1.2抽象共同属性 3.2方法注入 3.2.1基本的方法替换 3.2.2获取器注入 3.3注入非springbean 3.4注册自定义属性编辑器 3.5使用spring的特殊bean 3.5.1后处理bean 3.5.2bean工厂的后处理 3.5.3配置属性的外在化 3.5.4提取文本消息 3.5.5程序事件的解耦 3.5.6让bean了解容器 3.6脚本化的bean 3.6.1给椰子上lime 3.6.2脚本化bean 3.6.3注入脚本化bean的属性 3.6.4刷新脚本化bean 3.6.5编写内嵌的脚本化bean 3.7小结 第4章通知bean 4.1aop简介 4.1.1定义aop术语 4.1.2springaop的支持 4.2创建典型的spring切面 4.2.1创建通知 4.2.2定义切点和通知者 4.2.3使用proxyfactorybean 4.3自动代理 4.3.1为spring切面创建自动代理 4.3.2自动代理@aspectj切面 4.4定义纯粹的pojo切面 4.5注入aspectj切面 4.6小结 第二部分企业spring 第5章使用数据库 5.1spring的数据访问哲学 5.1.1了解spring数据访问的异常体系 5.1.2数据访问的模板化 5.1.3使用dao支持类 5.2配置数据源 5.2.1使用jndi数据源 5.2.2使用数据源连接池 5.2.3基于jdbc驱动的数据源 5.3在spring里使用jdbc 5.3.1处理失控的jdbc代码 5.3.2使用jdbc模板 5.3.3使用spring对jdbc的dao支持类 5.4在spring里集成hibernate 5.4.1选择hibernate的版本 5.4.2使用hibernate模板 5.4.3建立基于hibernate的dao 5.4.4使用hibernate3上下文会话 5.5spring和java持久api 5.5.1使用jpa模板 5.5.2创建一个实体管理器工厂 5.5.3建立使用jpa的dao 5.6spring和ibatis 5.6.1配置ibatis客户模板 5.6.2建立基于ibatis的dao 5.7缓存 5.7.1配置缓存方案 5.7.2缓存的代理bean 5.7.3注解驱动的缓存 5.8小结 第6章事务管理 6.1理解事务 6.1.1仅用4个词解释事务 6.1.2理解spring对事务管理的支持 6.2选择事务管理器 6.2.1jdbc事务 6.2.2hibernate事务 6.2.3jpa事务 6.2.4jdo事务 6.2.5jta事务 6.3在spring中编写事务 6.4声明式事务 6.4.1定义事务参数 6.4.2代理事务 6.4.3在spring2.0里声明事务 6.4.4定义注释驱动事务 6.5小结 第7章保护spring 7.1springsecurity介绍 7.2验证用户身份 7.2.1配置providermanager 7.2.2根据数据库验证身份 7.2.3根据ldap仓库进行身份验证 7.3控制访问 7.3.1访问决策投票 7.3.2决定如何投票 7.3.3处理投票弃权 7.4保护web应用程序 7.4.1代理springsecurity的过滤器 7.4.2处理安全上下文 7.4.3
Spring是一个开源的Java框架,用于构建企业级应用程序。它提供了一种轻量级的、非侵入式的开发方式,通过依赖注入和面向切面编程等特性,简化了Java应用程序的开发过程。 以下是关于Spring学习的一些笔记: 1. IoC(控制反转):Spring通过IoC容器管理对象的创建和依赖关系的注入。通过配置文件或注解,将对象的创建和依赖关系的维护交给Spring容器来管理,降低了组件之间的耦合度。 2. DI(依赖注入):Spring通过依赖注入将对象之间的依赖关系解耦。通过构造函数、Setter方法或注解,将依赖的对象注入到目标对象中,使得对象之间的关系更加灵活和可维护。 3. AOP(面向切面编程):Spring提供了AOP的支持,可以将与业务逻辑无关的横切关注点(如日志、事务管理等)从业务逻辑中分离出来,提高了代码的可重用性和可维护性。 4. MVC(模型-视图-控制器):Spring提供了一个MVC框架,用于构建Web应用程序。通过DispatcherServlet、Controller、ViewResolver等组件,实现了请求的分发和处理,将业务逻辑和视图展示进行了分离。 5. JDBC和ORM支持:Spring提供了对JDBC和ORM框架(如Hibernate、MyBatis)的集成支持,简化了数据库访问的操作,提高了开发效率。 6. 事务管理:Spring提供了对事务的支持,通过声明式事务管理和编程式事务管理,实现了对数据库事务的控制和管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值