资讯专栏INFORMATION COLUMN

Spring之旅 - 3.0、3.1、4.0导引

leon / 639人阅读

摘要:之旅简化开发的使命简化开发为了降低开发的复杂性,采取如下关键策略基于的轻量级和最小侵入性编程通过依赖注入和面向接口实现松耦合基于切面和惯例进行声明式编程通过切面和模版减少样式代码依赖注入耦合性具有两面性一方面,紧密耦合的代码难以测试难以复

Spring之旅 简化Java开发

Spring的使命:简化Java开发

为了降低Java开发的复杂性,采取如下关键策略:
基于POJO的轻量级和最小侵入性编程
通过依赖注入和面向接口实现松耦合
基于切面和惯例进行声明式编程
通过切面和模版减少样式代码

依赖注入

* 耦合性具有两面性(two-headed beast).

一方面,紧密耦合的代码难以测试、难以复用、难以理解,并且典型地表现“打地鼠”式的bug特性(修复一个bug,将会出现一个或者更多新的bug)
另一方面,一定程度的耦合又是必须的--完全没有耦合的代码什么也做不了

* 通过DI,对象的依赖关系将由系统中负责协调各对象的第三方租件在创建对象的时候进行设定。对象无需自行创建或管理它们依赖关系,依赖关系将被自动
注入到需要它们的对象当中去
* 依赖注入会将所依赖的关系自动交给目标对象,而不是让对象自己去获取依赖

构造器注入(constructor injection)

创建应用组件之间协作的行为通常称为装配(wiring)
SlayDragonQuestBraveKnightPrintStream如何装配起来?
XML(knights.xml)和Java描述配置(KnightConfig)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 基于Java的配置
 * 
 * @Configuration注解表明这个类是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节
 */
@Configuration
public class KnightConfig {

    @Bean
    public Knight knight(){
        return new BraveKnight(quest());
    }
    
    @Bean
    public Quest quest(){
        return new SlayDragonQuest(System.out);
    }
}

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

/**
 * 应用上下文容器的demo
 * 
 */
public class ApplicationContextDemo {

    //在指定的文件系统中查找knight.xml文件
    ApplicationContext context_1 = new FileSystemXmlApplicationContext("c:/knight.xml");
    //从所有的类路径下查找knight.xml文件
    ApplicationContext context_2 = new ClassPathXmlApplicationContext("knight.xml");
    //从Java配置中加载应用上下文
    ApplicationContext context_3 = new AnnotationConfigApplicationContext(com.leaf.u_spring.chapter01.KnightConfig.class); 
    
    
}
应用切面

DI能够让相互协作的软件组织保持松耦合,而面向切面编程(aspect-oriented programming, AOP)允许你把遍布应用各处的功能分离出来形成可重用的组件

关注点是横切面,如将安全、事务和日志关注点和核心业务逻辑相分离

使用模板消除样板式代码

样板式代码(boilerplate code)

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

/**
 * 样板式代码(boilerplate code)
 * 模拟JDBC操作
 * 
 */
public class BoilerplateCode {
    
    DataSource dataSource = null;
    
    String sql = "select id, firstname, lastname, salary from employee where id=?";

    //改造前
    public Employee getEmployeeById(long id){
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        
        try {
            conn = dataSource.getConnection();
            //查找员工
            stmt = conn.prepareStatement(sql);
            
            rs = stmt.executeQuery();
            Employee employee = null;
            if(rs.next()){
                //根据数据创建对象
                employee = new Employee();
                employee.setId(rs.getLong("id"));
                employee.setFirstName(rs.getString("firstname"));
                employee.setLastName(rs.getString("lastname"));
                employee.setSalary(rs.getBigDecimal("salary"));
            }
            return employee;
        } catch (SQLException e) {
            // 扑捉异常,也做不了太多事
        } finally {
            if(rs != null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            
            if(stmt != null){
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            
            if(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        
        return null;
    }
    
    private JdbcTemplate jdbcTemplate;
    //改造后
    //模板能够让你的代码关注于自身的职责
    public Employee getEmployeeById_1(long id){
        //SQL查询
        return jdbcTemplate.queryForObject(sql, new RowMapper(){
            //将结果匹配为对象
            @Override
            public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
                Employee employee = new Employee();
                employee.setId(rs.getLong("id"));
                employee.setFirstName(rs.getString("firstname"));
                employee.setLastName(rs.getString("lastname"));
                employee.setSalary(rs.getBigDecimal("salary"));
                return employee;
            }
            //指定查询参数
        }, id);
    }
}

class Employee {
    
    private Long id;
    private String firstName;
    private String lastName;
    private BigDecimal salary;
    
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public BigDecimal getSalary() {
        return salary;
    }
    public void setSalary(BigDecimal salary) {
        this.salary = salary;
    }
    
}
Spring 容器

在基于Spring的应用中,你的应用对象生存于Spring容器(container)中。

Spring容器负责创建对象,装配它们,配置它们并管理它们的整个生命周期,从生存到死亡(new到finalize)

应用上下文,Spring容器的一种

AnnotationConfigApplicationContext:从一个或多个基于Java的配置类中加载Spring应用上下文

AnnotationConfigWebApplicationContext:从一个或多个基于Java的配置类中加载Spring Web应用上下文

ClassPathXmlApplicationContext:从类路径下的一个或多个XML配置文件中加载上下文定义,把应用上下文的定义文件作为类资源

FileSystemXmlApplicationContext:从文件系统下的一个或多个XML配置文件中加载上下文定义

XmlWebApplicationContext:从Web应用下的一个或多个XML配置文件中加载上下文定义

bean的生命周期

Spring对bean进行实例化

Spring将值和bean的引用注入到bean对应的属性中

如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBeanName()方法

如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入

如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来

如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessBeforeInitialization()方法

如果bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()方法。
类似地,如果bean使用了init-method声明了初始化方法,该方法也会被调用

如果bean实现了BeanPostProcessor接口,Spring将调用它们的afterProcessBeforeInitialization()方法

此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁

如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。
同样,如果bean使用destory-method声明了销毁方法,该方法也会被调用

Spring模块

在Spring4.0中,Spring框架的发布版包括了20个不同的模块,每个模块会有3个JAR文件(二进制类库、源码的JAR文件以及JavaDoc的JAR文件)

Spring核心容器,bean工厂、应用上下文等

Spring的AOP模块,AOP、Aspects

数据访问和集成,JDBC、Transaction、ORM、OXM、Messaging、JMS

WEB与远程调用,WEB、WEB servlet、WEB portlet、WebSocket

Instrumentation,为Tomcat提供了一个织入代理,能够为Tomcat传递类文件

Spring Portfolio

Spring Web Flow ,为基于流程的会话式Web应用提供了支持

Spring Web Service

Spring Security,利用Spring AOP,Spring Security为Spring应用提供了声明式的安全机制

Spring Integration,提供了多种通用应用集成模式的Spring声明式风格实现

Spring Batch

Spring Data 支持关系型数据库和非关系型数据库

Spring Social 社交网络扩展模块

Spring Mobile移动应用

Spring for Android

Spring Boot大量依赖于自动配置技术

Spring 3.1新特性

引入环境profile功能,解决各种环境(开发、测试、生产)选择不通配置的问题

添加了多个enable注解,注解启用Spring的特定功能

添加了Spring对声明式缓存的支持,能够使用简单的注解声明缓存边界和规则

新添加的用于构造器注入的c命名空间

开始支持Servlet3.0,包括基于Java的配置中声明Servlet和Filter

改善对JPA的支持

自动绑定路径变量到模型属性中

提供了@RequestMappingproduces和consumes属性,用于匹配请求中的Accept和Content-Type头部信息

提供了@RequestPart注解,用于将multipart请求中的某些部分绑定到处理器的方法参数中

支持flash属性以及用于在请求间存放flash属性的RedirectAttributes类型

Spring 3.2新特性

可以使用Servlet3.0的异步请求

引入了Spring MVC测试框架

基于RestTemplate的客户端的测试支持

@ControllerAdvice注解能够将通用的@ExceptionHandler、@InitBinder和@ModelAttributes方法集中到一个类中,并应用到所有控制器上

支持完整的内容协商(full content negotiation)

@MatrixVariable注解能绑定矩阵变量到方法参数中

基础的抽象类AbstractDispatcherServletInitializer能够非常便利地配置DispatcherServlet

新增了ResponseEntityExceptionHandler

RestTemplate和@RequestBody的参数可以支持泛型

RestTemplate和@RequestMapping可以支持HTTP PATCH方法

在拦截器匹配时,支持使用URL模式将其排除在拦截器的处理功能之外

@Autowired @Value @Bean

@DateTimeFormat

提供了对JCache5.0的支持

支持定义全局来解析和渲染日期和时间

在集成测试中,能够配置和加载WebApplicationContent

在集成测试中,能够针对request和session作用域的bean进行测试

Spring 4.0 新特性

支持WebSocket

提供高层次的面向消息的编程模型,基于SockJS

支持Java8特性

添加了条件化创建bean的功能

包含了Spring RestTemplate的一个新的异步实现

Spring 致力于简化企业级Java开发,促进代码的松散耦合
依赖注入和AOP是Spring框架最核心的部分
引用:《Spring In Action 4》第1章

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/70887.html

相关文章

  • Spring新功能

    摘要:新特性重要功能升级为了解决各种环境下如开发测试和生产选择不同配置的问题,引入了环境功能。这个消息模块支持的功能,同时提供了基于模板的方式发布消息是第一批支持特性的框架,比如它所支持的表达式。 Spring 3.1新特性 重要功能升级 为了解决各种环境下(如开发、测试和生产)选择不同配置的问题,Spring 3.1引入了环境profile功能。借助于profile,就能根据应用部署在什...

    baiy 评论0 收藏0
  • Pandas之旅(三)最实用的Merge, Join,Concat方法详解

    摘要:基于上的我们还可以实现几个基于的,还是老样子,先让我们创建两个好了,现在我们想要实现两个的,但是条件是通过的和的这样我们也可以得到结果。 Merge, Join, Concat 大家好,我有回来啦,这周更新的有点慢,主要是因为我更新了个人简历哈哈,如果感兴趣的朋友可以去看看哈: 我的主页 个人认为还是很漂亮的~,不得不说,很多时候老外的设计能力还是很强。 好了,有点扯远了,这一期我想和...

    CloudwiseAPM 评论0 收藏0
  • Spring之旅第二站:bean、新特性。。。

    摘要:除了,还简单介绍了对的支持,可以帮助应用将散落在各处的逻辑汇集于一处切面。当装配的时候,这些切面能够运行期编织起来,这样就能呢个非常有效的赋予新功能。 第1章 Spring之旅 说明 1、本文参考了《Spring 实战》重点内容,参考了GitHub上的代码 2、每个人的学习方式不一样,但目的是一样的,活学活用。最近一直在听《我们不一样》 3、本文只为记录作为以后参考,要想真正领悟Sp...

    luodongseu 评论0 收藏0
  • 关于web.xml配置的那些事儿

    摘要:的版本增加了对事件监听程序的支持,事件监听程序在建立修改和删除会话或环境时得到通知。元素指出事件监听程序类。过滤器配置将一个名字与一个实现接口的类相关联。 1.简介 web.xml文件是Java web项目中的一个配置文件,主要用于配置欢迎页、Filter、Listener、Servlet等,但并不是必须的,一个java web项目没有web.xml文件照样能跑起来。Tomcat容器/...

    zhichangterry 评论0 收藏0

发表评论

0条评论

leon

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<