Spring 是java web 开发中广泛使用的一个东西,我们用它肯定是有原因的,很多初学者在学Spring的时候不知道为什么用spring,用Spring有哪些好处,不知道为什么要学它,我简单介绍一下它的主要作用。
Spring 是一个Java框架,不是组件,相信大多数学spring的同学大多用过tomcat了,那他们两个学起来又有什么不同呢?
Tomcat 是web容器,你把写好的java 代码打成war包扔给他,他就会帮你运行,他帮你自动监听本地端口,解析浏览器发来的 http 请求,解析url,找到url对应的函数,然后执行这个函数,再返回给浏览器。可以说他是一个组件。
而 Spring 是一个框架,框架的意思是,套路我告诉你,你这么写就可以了,剩下的部分框架帮你做。那 Spring 帮我们做了哪些事情呢?
我们在讲他的作用的时候先来看一下最最最原始的操作数据库的代码,以下面的伪代码为例,从他的演变过程来看,为什么要用Spring。
添加 jdbc 连接驱动 jar包,这里省略关闭、处理异常等…
public class Demo1 {
static final String DB_URL = "jdbc:mysql://localhost:3306/databaseweb";
static final String USER = "root";
static final String PASS = "1234";
public static void main(String[] args) throws Exception{
Connection conn = null;
Statement stat = null;
Class.forName("com.mysql.jdbc.Driver");
conn = (Connection) DriverManager.getConnection(DB_URL,USER,PASS);
// 执行查询
stat = conn.createStatement();
String sql = "SELECT * FROM tb_person";
ResultSet rs = stat.executeQuery(sql);
// 输出查询结果
while(rs.next()){
System.out.print(rs.getInt("id")+",");
System.out.print(rs.getString("name")+",");
System.out.print(rs.getString("sex")+",");
System.out.print(rs.getInt("age"));
System.out.print("\n");
}
// 省略关闭连接.....
}
(以上部分代码转自网络)
这样写,一气呵成,真爽,一个类就完成了,而这时面向函数式编程,java是面对对象的
(为什么要面对对象?是因为方便开发、维护等…)
可能有人觉得这样写没问题,挺好的,我也觉得这样写完全没毛病,因为可能他只需要查看一下这个表。
但是我们在开发一个web项目时,有好多张表,好多次增删改查,如果每次都这么写,那岂不是得累死?没错,所以我们就有了以下改进:
JDBCUtil
public class JdbcUtil {
private static String url = "jdbc:mysql://localhost:3306/jdbcDB?useSSL=true";
private static String username = "root";
private static String password = "root";
private JdbcUtil(){}
public static Connection getConn() throws SQLException{
return DriverManager.getConnection(url,username,password);
}
}
Demo2
public class Demo1 {
public static void main(String[] args) throws Exception{
try{
Connection conn = JDBCUtil.getConnection();
Statement stat = conn.createStatement();
String sql = "SELECT * FROM tb_person";
ResultSet rs = stat.executeQuery(sql);
// 输出查询结果
while(rs.next()){
System.out.print(rs.getInt("id")+",");
System.out.print(rs.getString("name")+",");
System.out.print(rs.getString("sex")+",");
System.out.print(rs.getInt("age"));
System.out.print("\n");
}
conn.close();
}
这样是不是舒服了很多?以后写起代码来只需要 getConn() 就行了.
有一天我发现我的数据库列名起的不合适,name 需要改成 nickName,我们这时发现,数据库列名一改,代码中所有用到这一列的地方( rs.getString(“name”))都要改 ,代码多了还找不到哪里要改,想想都可怕。
class User(){
int id;
String name;
//省略其他属性....
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
//省略其他get set..
public String toString(){
//省略...
}
}
UserDataAccessObject.java
//将 ResultSet 转化成 User 实体类
public UserDataAccessObject{
public static User toUer(ResultSet rs){
User user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
//其他属性...
return user;
}
//省略增删改
}
Demo3
Connection conn = JDBCUtil.getConnection();
Statement stat = conn.createStatement();
String sql = "SELECT * FROM tb_person";
ResultSet rs = stat.executeQuery(sql);
User user = UserDataAccessObject.toUser(rs);
System.out.println(user);
conn.close();
这样我们使用的时候只需要 DBResultHandleUtil.toUser(rs); 就自动将结果集转为 User 了,以后数据库改动的时候,只需要改 UserDataAccessObject 就可以了,写着写着,发现UserDataAccessObject名字太长,以后就简写成了 UserDAO
之前我们查询的时候只是查询所有用户,随着我们的业务量增加,来了新的需求,只推广我们的儿童产品给有购买能力的成人用户,因此我们需要查询 age > 18 的,按照之前的方式是放在 UserDAO 里面进行的,
class UserDAO{
public static List<User> query(String sql){
//...
}
}
UserService.java
class UserService{
List<User> queryAll(){
String sql = "select * from user";
return UserDAO.userDao.query(sql);
}
List<User> queryAdult(){
String sql = "select * from user where age > 18";
return UserDAO.userDao.query(sql);
}
}
现在管你什么需求,新的来了,我只需要在 UserService 添加新的方法就行了,你要是想改回来,那我就把调用的地方改回原来的函数就行,我真机智,爽~
UserDAO.java
interface UserDAO{
List<User> findAll(String sql);
}
UserDAOImplForMysql.java
class UserDAOImplForMysql implements UserDAO{
public List<User> findAll(String sql){
//...
}
}
UserService.java
class UserService{
UserDAO userDao = new UserDAOImplForMysql(); //依赖实际的实现类
List<User> queryAll(){
String sql = "select * from user";
return userDao.findAll.query(sql);
}
List<User> queryAdult(){
String sql = "select * from user where age > 18";
return userDao.userDao.findAll(sql);
}
}
程序猿想,这样你再变,我只需要改一下 new 所在位置改为 UserDAOImplForOrcle 就行了,哼,休想让我加班!
Spring是管理 java 类( 又称 java bea) 的容器,他把类之间的耦合关系的管理权限从程序猿交给计算机去做,这称之为 IOC (inverse of control 控制反转),他的思想是将自己写好的类,放入 Spring 的 Bean容器中,放入方式有多种,称之为 DI (Dependency Injection,依赖注入),可以选择依赖的方式,比如按照类型,按照类名称等。
IOC 和 DI 是 Spring 的两大特性,也是spring的核心思想。
Spring 一词翻译为春天,他的到来寓意程序猿将真正的从寒冬中走出,迎来春天。
Spring 的使用方式有配置文件和注解两种。下面简单介绍,以注解的使用时候和上面不适用 Spring 的区别:
还是上面的代码
省略在配置文件中开启自动扫描包
UserDAOImplForMysql.java
//添加 @Bean 注解,让spring 知道这个类允许他接管
@Bean
class UserDAOImplForMysql implements UserDAO{
public List<User> findAll(String sql){
//...
}
}
UserService.java
@Component
class UserService{
//不再需要new了,只需要添加注解,Spring自动帮我们选择对应的 bean
//UserDAO userDao = new UserDAOImplForMysql(); //依赖实际的实现类
@Autowirte
UserDAO userDao; //使用一个注解就可以让 spring 自动帮我们注入对应的 bean
List<User> queryAll(){
String sql = "select * from user";
return userDao.findAll.query(sql);
}
List<User> queryAdult(){
String sql = "select * from user where age > 18";
return userDao.userDao.findAll(sql);
}
}
使用spring 后,类间的耦合关系消除了很多很多,春天(Spring)来了,尽情在春天(Spring)中自由徜徉把~
本文仅为 Spring 思想初探,不足以作为入门等,更多相关细节和知识,大家可以自行了解。
如