Java——Spring超详细总结
Spring概述
⼀、简化Java开发
Spring为了降低Java开发的复杂性,采⽤了以下四种策略
基于POJO的轻量级和最⼩侵⼊性编程;
通过依赖注⼊和⾯向接⼝实现松耦合;
基于切⾯和惯例进⾏声明式编程;
通过切⾯和模板减少样板式代码。
下⾯简单介绍⼀下这四种策略分别是什么:
1、激发POJO的潜能:
Spring竭⼒避免因⾃⾝的API⽽弄乱你的应⽤代码。Spring不会强迫你实现Spring规范的接⼝或继承Spring
规范的类,相反,在基于Spring构建的应⽤中,它的类通常没有任何痕迹表明你使⽤了Spring。最坏的场景是,⼀个类或许会使⽤Spring注解,但它依旧是POJO
2、依赖注⼊:
任何⼀个有实际意义的应⽤(肯定⽐Hello World⽰例更复杂)都会由两个或者更多的类组成,这些类相互之间进⾏协作来完成特定的业务逻辑。按照传统的做法,每个对象负责管理与⾃⼰相互协作的对象(即它所依赖的对象)的引⽤,这将会导致⾼度耦合和难以测试的代码。通过DI,对象的依赖关系将由系统中负责协调各对象的第三⽅组件在创建对象的时候进⾏设定。对象⽆需⾃⾏创建或管理它们的依赖关系依赖关系将被⾃动注⼊到需要它们的对象当中去。
3、⾯向切⾯:
DI能够让相互协作的软件组件保持松散耦合,⽽⾯向切⾯编程(aspect-oriented programming,AOP)允许你把遍布应⽤各处的功能分离出来形成可重⽤的组件。⾯向切⾯编程往往被定义为促使软件系统实现关注点的分离⼀项技术。系统由许多不同的组件组成,每⼀个组件各负责⼀块特定功能。除了实现⾃⾝核⼼的功能之外,这些组件还经常承担着额外的职责。诸如⽇志、事务管理和安全这样的系统服务经常融⼊到⾃⾝具有核⼼业务逻辑的组件中去,这些系统服务通常被称为横切关注点,因为它们会跨越系统的多个组件。
4、使⽤模板消除样板式代码:
有过java开发经验的同学应该都知道在使⽤JDBC操作数据库时的步骤有多繁琐,下⾯我来看⼀下JDBC操作数据库的代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/person";
String user = "root";
String pwd = "admin";
String sql = "select * from student";
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
Class.forName("sql.jdbc.Driver");
conn = Connection(url,user,pwd);
st = ateStatement();
//执⾏查询语句,另外也可以⽤execute(),代表执⾏任何SQL语句
rs = st.executeQuery(sql);
()) {
System.out.Object(1) + " " +
}
//分别捕获异常
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
//判断资源是否存在
if(rs != null) {
rs.close();
/
/显⽰的设置为空,提⽰gc回收
rs = null;
}
if(st != null) {
st.close();
st = null;
}
if(conn != null) {
conn.close();
conn = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
估计很少有读者能将这段代码⼀⾏⼀⾏的看完,因为实在是太长了。
JDBC不是产⽣样板式代码的唯⼀场景。在许多编程场景中往往都会导致类似的样板式代码,JMS、JNDI和使⽤REST服务通常也涉及⼤量的重复代码。Spring旨在通过模板封装来消除样板式代码。Spring的JdbcTemplate使得执⾏数据库操作时,避免传统的JDBC样板代码成为了可能。
⼆、容纳Bean
在基于Spring的应⽤中,你的应⽤对象⽣存于Spring容器(container)中。如下图所⽰,Spring容器负
责创建对象,装配它们,配置它们并管理它们的整个⽣命周期,从⽣存到死亡(在这⾥,可能就是new到finalize())。
Spring容器是Spring的核⼼,Spring⾃带了多个容器实现,可以归为两种不同的类型。bean⼯⼚(由org.springframework.beans.factory.eanFactory接⼝定义)是最简单的容器,提供基本的DI⽀持。应⽤上下⽂(由t.ApplicationContext接⼝定义)基于BeanFactory构建,并提供应⽤框架级别的服务,例如从属性⽂件解析⽂本信息以及发布应⽤事件给感兴趣的事件监听者。通常我们使⽤的是应⽤上下⽂,因为bean⼯⼚对⼤多数开发者来说功能⽐较薄弱。
1、使⽤应⽤上下⽂:
Spring⾃带了多种类型的应⽤上下⽂
AnnotationConfigApplicationContext:从⼀个或多个基于Java的配置类中加载Spring应⽤上下⽂。
AnnotationConfigWebApplicationContext:从⼀个或多个基于Java的配置类中加载Spring Web应⽤上下⽂。
ClassPathXmlApplicationContext:从类路径下的⼀个或多个XML配置⽂件中加载上下⽂定义,把应⽤上下⽂的定义⽂件作为类资源。
FileSystemXmlapplicationcontext:从⽂件系统下的⼀个或多个XML配置⽂件中加载上下⽂定义。
XmlWebApplicationContext:从Web应⽤下的⼀个或多个XML配置⽂件中加载上下⽂定义
2、bean的⽣命周期:
在传统的Java应⽤中,bean的⽣命周期很简单。使⽤Java关键字new进⾏bean实例化,然后该bean就可以使⽤了。⼀旦该bean不再被使⽤,则由Java⾃动进⾏垃圾回收。相⽐之下,Spring容器中的bean的⽣命周期就显得相对复杂多了
1、Spring对bean进⾏实例化;
2、Spring将值和bean的引⽤注⼊到bean对应的属性中;
3、如果bean实现了BeanNameAware接⼝,Spring将bean的ID传递给setBean-Name()⽅法;
4、如果bean实现了BeanFactoryAware接⼝,Spring将调⽤setBeanFactory()⽅法,将BeanFactory容器实例传⼊;
5、如果bean实现了ApplicationContextAware接⼝,Spring将调⽤setApplicationContext()⽅法,将bean所在的应⽤上下⽂的引⽤传⼊进来;
6、如果bean实现了BeanPostProcessor接⼝,Spring将调⽤它们的post-ProcessBeforeInitialization()⽅法;
7、如果bean实现了InitializingBean接⼝,Spring将调⽤它们的after-PropertiesSet()⽅法。类似地,如果bean使⽤init-method声明了初始化⽅法,该⽅法也会被调⽤;
8、如果bean实现了BeanPostProcessor接⼝,Spring将调⽤它们的post-ProcessAfterInitialization()⽅法;
9、此时,bean已经准备就绪,可以被应⽤程序使⽤了,它们将⼀直驻留在应⽤上下⽂中,直到该应⽤上下⽂被销毁;
10、如果bean实现了DisposableBean接⼝,Spring将调⽤它的destroy()接⼝⽅法。同样,如果bean使⽤destroy-method声明了销毁⽅法,该⽅法也会被调⽤
3、Spring的核⼼模块:
我们来逐⼀分析⼀下Sping的各个组成模块
Spring核⼼容器
容器是Spring框架最核⼼的部分,它管理着Spring应⽤中bean的创建、配置和管理。在该模块中,包括了Spring bean⼯⼚,它为Spring提供了DI的功能。基于bean⼯⼚,我们还会发现有多种Spring应⽤上下⽂的实现,每⼀种都提供了配置Spring的不同⽅式。
除了bean⼯⼚和应⽤上下⽂,该模块也提供了许多企业服务,例如E-mail、JNDI访问、EJB集成和调度。所有的Spring模块都构建于核⼼容器之上。当你配置应⽤时,其实你隐式地使⽤了这些类。
Spring的AOP模块
在AOP模块中,Spring对⾯向切⾯编程提供了丰富的⽀持。这个模块是Spring应⽤系统中开发切⾯的基础。与DI⼀样,AOP可以帮助应⽤对象解耦。借助于AOP,可以将遍布系统的关注点(例如事务和安全)从它们所应⽤的对象中解耦出来。
数据访问和集成
使⽤JDBC编写代码通常会导致⼤量的样板式代码,例如获得数据库连接、创建语句、处理结果集到最后关闭数据库连接。Spring的JDBC和DAO(Data Access Object)模块抽象了这些样板式代码,使我们的数据库代码变得简单明了,还可以避免因为关闭数据库资源失败⽽引发的问题。该模块在多种数据库
服务的错误信息之上构建了⼀个语义丰富的异常层,以后我们再也不需要解释那些隐晦专有的SQL错误信息了!
Web与远程调⽤
MVC(Model-View-Controller)模式是⼀种普遍被接受的构建Web应⽤的⽅法,它可以帮助⽤户将界⾯逻辑与应⽤逻辑分离。Java从来不缺少MVC框架,Apache的Struts、JSF、WebWork和Tapestry都是可选的最流⾏的MVC框架。
Spring装配bean
⼀、Spring装配的三种⽅式
1、在XML中进⾏显⽰配置
2、在Java中进⾏显⽰配置
3、隐式的bean的发现机制和⾃动装配
⾄于哪⼀种装配⽅式好,这⾥没有统⼀的答案,读者可以选择适合⾃⼰的⽅案进⾏bean的装配
⼆、⾃动化装配bean
1、Spring 从两个⾓度来实现⾃动化装配bean :
组件扫描:Spring会⾃动发现应⽤上下⽂中所创建的bean
⾃动装配:Spring⾃动满⾜bean之间的依赖
2、创建可被发现的bean:
接下来我将⽤⼀个CD播放器案例来说明整个⾃动化装配bean的过程,该项⽬是⼀个Maven项⽬,进⾏实验前需要引⼊相关Maven配置⽂件,对Maven还不了解的同学建议去学习相关资料,这⾥不再赘述
第⼀步:创建CompactDisc接⼝,接⼝中包含了⼀个play()⽅法
package soundsystem;
public interface CompactDisc {
void play();
}
CompactDisc的具体内容并不重要,重要的是你将其定义为⼀个接⼝。作为接⼝,它定义了CD播放器对⼀盘CD所能进⾏的操作。它将CD播放器的任意实现与CD本⾝的耦合降低到了最⼩的程度。
第⼆步:我们还需要⼀个CompactDisc的实现,SgtPeppers实现了CompactDisc接⼝
package soundsystem;
import org.springframework.stereotype.Component;
@Component //该类是⼀个组件类
public class SgtPeppers implements CompactDisc {
private String title = "曾经的你";
private String artist = "许巍";
@Override
public void play() {
System.out.println("Playing " + title + " by " + artist);
}
}
和CompactDisc接⼝⼀样,Sgtpeppers的具体内容并不重要。你需要注意的就是SgtPeppers类上使⽤了@Component注解。这个简单的注解表明该类会作为组件类,并告知Spring要为这个类创建bean。没有必要显式配置Sgtpeppers bean,因为这个类使⽤了@Component注解,所以Spring会为你把事情处理妥当。
第三步:我们声明了组件类之后Spring并不知道这个组件类,所以我们还需要开启组件扫描,让Spring去查相关的组件类。新建⼀个CDPlayerConfig类
package soundsystem;
import t.annotation.ComponentScan;
import t.annotation.Configuration;
@Configuration //Configuration注解表明该类是⼀个配置类
@ComponentScan //ComponentScan注解表⽰开启组件扫描,默认是扫描当前包下的组件
public class CDPlayerConfig {
/*@Bean
public CompactDisc compactDisc() {
return new SgtPeppers();
}
@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc) {
return new CDPlayer(compactDisc);
spring怎么读多个文件}*/
}
第四步:下⾯我们来测试⼀下⾃动装配是否成功
package soundsystem;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import st.context.ContextConfiguration;
import st.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class CDPlayTest {
@Autowired //@Autowired注解将CompactDisc注⼊到测试代码中,稍后会讲解到
private CompactDisc compactDisc;
@Test
public void play() {
compactDisc.play();
}
}
运⾏结果:
Playing 曾经的你 by 许巍
我们看到结果正常输出,说明我们的⾃动装配成功
3、⾃动装配中的注解介绍:
@Component:
@Component注解表明该类作为组件类,并告知Spring要为这个类创建bean,另外@Component中还
可以传⼊⼀个参数,⽤于为这个bean设置ID,如果你之前有过通过xml⽂件配置bean的经验话就知道在配置bean的时候就需要设置bean的id。
@Component("cdplay"),这个注解表明当前bean的ID为cdplay
@ComponentScan:
@ComponentScan默认会扫描与配置类相同的包,⽐如上⾯的程序中因为CDPlayerConfig类位于soundsystem包中,因此Spring将会扫描这个包以及这个包下的所有⼦包,查带有@Component注解的类。这样的话,就能发现CompactDisc,并且会在Spring中⾃动为其创建⼀个bean。我们也可以为该注解传⼊参数,让其扫描指定的包:
@ComponentScan(basePackages={"soundsystem","video"}),扫描soundsystem和video包下的组件
//直接在value属性中指明包的名称
@Configuration
@ComponentScan("soundsystem")
public class CDPlayerConfig{}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论