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开发,分别简单介绍了四大利器大概长什么样子。