Spring的根本使命:简化Java开发。

4种关键策略:

  • 基于POJO的轻量级和最小侵入性编程
  • 依赖注入和面向接口实现松耦合
  • 基于切面和惯例进行声明式编程
  • 通过切面和模板减少样板式代码

策略一: POJO的最小侵入性编程

Spring不会要强迫实现规范的接口或继承规范的类。在基于Spring构建的应用中,类通常不会表现出使用Spring的痕迹。
尽管POJO形式简单,仍可以通过依赖注入的方式来保持松散耦合。


策略二: 依赖注入

耦合:具有两面性,一方面,紧密耦合的代码难以测试、复用、理解,bug难以修复;另一方面,一定程度的耦合是必须的,不同类必须以适当的形式进行交互。

依赖注入:对象的依赖关系将由负责协调系统中各个对象的第三方组件在创建对象时设定,对象无需自行创建或管理他们的依赖关系。使用依赖注入的最大的好处就是松耦合。

三种依赖注入的方式:

  1. 构造器注入
  2. 接口注入
  3. setter方法注入

如何工作:
通过应用上下文装载bean的定义并把它们组装起来。


策略三: 应用切面

横切关注点:横跨系统的多个组件,这些组件除了自身核心的功能之外,还经常承担额外的职责,如:日志、事务管理、安全等。

xml声明一个切面:

 <aop:config>
     <aop:aspect ref="minstrel">  //管理切面方法的类

        <aop:pointcut id="embark"    //要调用切面的方法
            expression="excution(* *.embark())" />

        <aop:before pointcut-ref="embark"
                    method="singBefore" />

        <aop:after pointcut-ref="embark"
                    method="singAfter" />
     </aop:aspect>
 </aop:config>

各个组件并不知道有切面的存在,没有显式调用切面的方法,而作为切面的类仍是一个POJO没有任何代码表明它被作为一个切面使用。


策略四:使用模板消除样板式代码

使用JDBC、JMS、JNDI和REST服务通常会涉及大量的重复代码,Spring通过模板封装来消除样板式代码。

例如使用Spring的SimpleJdbcTemplate:

public Employee getEmployeeById(long id) {
    return jdbcTemplate.queryForObject(
        "select id, name, salary" + 
        "from employee where id=?",
        new RowMapper<Employee>() {
            public Employee mapRow(ResultSet rs,
                    int rowNum) throws SQLException {
                Employee employee = new Employee();
                employee.setId(rs.getLong("id"));
                employee.setName(rs.getString("name"));
                employee.setSalary(rs.getBigDecimal("salary"));
                return employee;
            }
        },
        id);
}

Spring容器

应用对象生存于Spring容器中,由容器创建、装配、配置,管理她们的整个生命周期,从创建到销毁。

容器的实现可分为两种:

  1. bean工厂(由BeanFactory接口定义):比较低级,不常用。
  2. 应用上下文(由ApplicationContext接口定义):基于BeanFactory之上构建,并提供面向应用的服务。

常见的3种应用上下文:

  1. ClassPathXmlApplicationContext:从classpath处获取xml文件来加载一个上下文。
  2. ClassPathXmlApplicationContext:从文件系统中获取xml文件来加载一个上下文。
  3. XmlWebApplicationContext:从web应用获取xml文件来加载一个上下文。

这三个类都是ApplicationContext接口的实现。

使用:
ApplicationContext context = new ClassPathXmlApplicationContext(“config.xml”);//config.xml在src目录下
ApplicationContext context = new FileSystemXmlApplicationContext(“d:/config.xml”);


Bean的生命周期

传统Java应用中的:
new进行实例化,就可以被使用,一旦不被使用,JVM自动回收

Spring容器中的Bean:
实例化,填充属性,(如果实现相应接口就)传BeanID,传BeanFactory容器实例,传应用上下文的引用,调用postProcessBeforeInitialization(),调用afterpropertiesSet(),如果声明了init-method,也调用该方法,调用postProcessAfterInitialization方法。
此时已经可以被应用程序使用,将一直驻留在应用上下文中,直到该应用上下文被销毁。
如果Bean实现了DisosableBean接口,调用destroy()接口方法,如果用destroy-method声明了销毁方法,就调用该方法。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐