Spring的核心是dependency injection (DI) and aspect-oriented programming (AOP).
第一章概览一下什么是Spring,以及DI和AOP是怎么解耦(decoupling )应用组件的。
第二章讲模块、bean怎么连接起来,我们会了解spring提供的三种配置方式:自动配置,基于java的配置和用xml配置。【wiring beans,不清楚标准翻译法,暂翻译为连接,装配,反正大概就是这个意思】
第三章延续第二章讲一些高级的技术技巧,包括带有特定条件的配置,自动装配时的歧义处理,域,以及Spring表达式语言。【Spring Expression Language)】
第四章讲Spring的AOP如何解耦全路服务(比如安全控制及审计)【decouple system-wide services (such as security and auditing) 】
1.1 简化java开发
Spring设计初衷是为简化企业级应用开发,但它的好处不止于此。
Spring的基本任务是:简化java开发!!
Spring简化策略:
1、用POJO-轻量化,高内聚。
2、用DI和面向接口编程-低耦合
3、用切面和约定-声明式编程
4、用切面和模板-减少固化的重复代码
【高内聚低耦合其实算是同一套概念,这里把1跟2分开感觉没有必要,单纯的POJO本身并没有解决问题。】
1.1.1 Spring不对POJO做强制规范。【你想要什么就加,不想要的可以不加。没有茶位费,一切自助餐】
1.1.2 DI【TODO:概念链接】
1 public class BraveKnight implements Knight { 2 private Quest quest; 3 4 public BraveKnight(Quest quest) { 5 this.quest = quest; 6 } 7 8 public void embarkOnQuest() { 9 quest.embark(); 10 } 11 12 }
1 public class SlayDragonQuest implements Quest { 2 private PrintStream printStream; 3 4 public SlayDragonQuest(PrintStream printStream) { 5 this.printStream = printStream; 6 } 7 8 public void embark() { 9 printStream.println("Embarking on quest to slay the dragon"); 10 } 11 }
两个接口我就不写了,很显然的东西。。。
Spring提供了xml注入方式和java代码注入方式。xml文件位置在下文有,内容如下:
<?xml version="1.0" encoding="utf-8" ?> <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="knight" class="prep.jing.BraveKnight"> <constructor-arg ref="quest"/> </bean> <bean id="quest" class="prep.jing.SlayDragonQuest"> <constructor-arg value="#{T(System).out}"/> </bean> </beans>
应该很好理解,就是把System.out传给SlayDragonQuest,然后再把SlayDragonQuest传给BraveKnight。xml的测试代码如下(依赖spring的beans,context,core,自行百度spring maven找最近的用的人比较多的那个版本):
1 public class KnightMain { 2 public static void main(String[] args) { 3 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/knight.xml"); 4 Knight knight = context.getBean(Knight.class); 5 knight.embarkOnQuest(); 6 context.close(); 7 } 8 }
相应的,Spring还提供了java的方式,代码如下:
1 @Configuration 2 public class KnightConfig { 3 @Bean 4 public Knight knight(){ 5 return new BraveKnight(quest()); 6 } 7 8 @Bean 9 public Quest quest() { 10 return new SlayDragonQuest(System.out); 11 } 12 }
1.1.3 AOP【TODO:概念链接】
程序设计要高内聚低耦合,但是有些东西天生就是跟几乎所有类所有方法参和。比如安全控制,日志,事务处理,统计等等之类的。这个概念的理解应该没什么难度,解释成像上下班打卡一样?最基本最直观的感受是,这个方法调用之前,之后调用一段别的代码。直接上代码:
1 public class Minstrel { 2 private PrintStream printStream; 3 4 public Minstrel(PrintStream printStream) { 5 this.printStream = printStream; 6 } 7 8 public void singBeforeQuest() { 9 printStream.println("Fa la la, the knight is so brave"); 10 } 11 12 public void singAfterQuest() { 13 printStream.println("Tee he he, the brave knight did embark on a quest"); 14 } 15 }
xml文件修改下就可以了。测试类是同一个见上文。
<?xml version="1.0" encoding="utf-8" ?> <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="knight" class="prep.jing.BraveKnight"> <constructor-arg ref="quest"/> </bean> <bean id="quest" class="prep.jing.SlayDragonQuest"> <constructor-arg value="#{T(System).out}"/> </bean> <bean id="minstrel" class="prep.jing.Minstrel"> <constructor-arg value="#{T(System).out}"/> </bean> <aop:config> <aop:aspect ref="minstrel"> <aop:pointcut id="embark" expression="execution(* *.embarkOnQuest(..))"/> <aop:before pointcut-ref="embark" method="singBeforeQuest"/> <aop:after pointcut-ref="embark" method="singAfterQuest"/> </aop:aspect> </aop:config> </beans>
1.1.4 代码模板化
这里只给了一段代码体会一下,没有给出具体的可运行的范例教程。
例子用的是数据库查询的例子,模板封住了数据库连接,异常处理,清理工作,以及清理工作的异常处理这样的重复代码。
1 public Employee getEmployeeById(String id) { 2 return jdbcTemplate.queryForObject("select id, firstname, lastname, salary from employee where id=?", new RowMapper<Employee>() { 3 @Override 4 public Employee mapRow(ResultSet rs, int rowNum) throws SQLException { 5 Employee employee = new Employee(); 6 employee.setId(rs.getLong("id")); 7 employee.setFirstName(rs.getString("firstname")); 8 employee.setLastName(rs.getString("lastname")); 9 employee.setSalary(rs.getBigDecimal("salary")); 10 return employee; 11 } 12 }, id); 13 }
至此,1.1就已经完了,主要讲了Spring的核心精神是简化java开发,分别简单介绍了四大利器大概长什么样子。