Spring深入浅出
一、什么是Spring框架
博主初学者,有误的地方请各位大牛多多指正。步入正题,要想知道Spring框架是什么,首先的了解什么是框架。框架是一个集成了一套工具的工具包,或者说是建造房子时候的大体结构。在开发过程中,程序有一些固定的代码,为了减少代码量,所以引入了“框架”。而Spring框架则是一个集成了切面编程、MVC、Web、对象实体映射、JDBC和DAO等多种功能模块。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架。
二、Spring的构成
Spring的结构如图
1、Spring Core:Spring的核心容器
一个最重要的部分,在Spring中通过Bean的方式去管理,组织各个模块。通过声明的方式注入,既简单又容易阅读。
2、Spring Context:对于对象、bean的管理
通过ApplicationContext获取已经初始化的bean。以此实现控制反转(IOC)的操作。说到控制反转,它就是是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
--粘贴自百度百科
说白了就是不需要你去管理对象,把这一系列的操作都交给Spring就好。
使用context去创建一个对象:
ClassPathXmlApplicationContext context = new ApplicationContext("beans.xml");
3、Spring Dao :管理JDBC
原生的JDBC:需要手动去数据库的驱动从而拿到对应的连接。
1 Connection conn = null;2 PreparedStatement stat = null;3 ResultSet rs = null;4 String sql = "select * from user where username = ? and passwd = ?";5 try{6 conn =dataSource.getConnection();7 stat =conn.prepareStatement(sql);8 stat.setString(1, username);9 stat.setString(2, passwd);10 rs =stat.executeQuery();11 if(rs.next()) {12 return true;13 }14 } catch(SQLException e) {15 e.printStackTrace();16 }
但是在Spring框架下,你只需要加这段代码:
bean.xml
1
2
3
4
5
1
2
3
4
5
6
7
把原生的JDBC给改为:
UserDao.java
1 privateDataSource dataSource;2 public voidsetDataSource(DataSource dataSource) {3 this.dataSource =dataSource;4 }5
6 public voidsave() {7 try{8 String sql = "insert into t_dept(deptName) values('test');";9 Connection con = null;10 Statement stmt = null;11 //连接对象
12 con =dataSource.getConnection();13 //执行命令对象
14 stmt =con.createStatement();15 //执行
16 stmt.execute(sql);17
18 //关闭
19 stmt.close();20 con.close();21 } catch(Exception e) {22 e.printStackTrace();23 }24 }
在需要的时候,这么用:
1 //使用Spring的自动装配
2 @Autowired3 privateJdbcTemplate template;4
5 @Override6 public voidsave() {7 String sql = "select * from user";8 template.query(sql);9 }
其中setDateSource方法是Spring封装好的一个方法,只需要对它进行设值就好。这个方法使用的是JdbcTemplate
三、以下是模仿Spring框架做的登录验证的代码,帮助理解:
MyContext.java(模仿Core容器生成对象)
1 packagecom.hxz.spring01.context;2
3 importjava.lang.reflect.Field;4 importjava.util.HashMap;5 importjava.util.Iterator;6 importjava.util.Map;7
8 importorg.dom4j.Document;9 importorg.dom4j.Element;10 importorg.dom4j.io.SAXReader;11
12 public classMyContext {13
14 //创建一个Map来存储bean对象和bean的id
15 Map context = new HashMap();16
17 /**
18 * 构造函数,创建bean对象19 *@paramcfgpath20 */
21 publicMyContext(String cfgpath) {22 //解析XML获取bean
23 SAXReader reader = newSAXReader();24 Document doc = null;25
26 try{27 doc = reader.read(MyContext.class.getClassLoader().getResource(cfgpath));28
29 //1、获取根节点Beans
30 Element root =doc.getRootElement();31 Iterator it =root.elementIterator();32
33 while(it.hasNext()) {34 //2、迭代获取子节点bean的id和class
35 Element bean =it.next();36 String id = bean.attributeValue("id");37 String className = bean.attributeValue("class");38
39 //3、通过获取的class获取bean对象的实例
40 Class clazz =Class.forName(className);41 Object o =clazz.newInstance();42
43 //4、获取bean节点中的propty属性并克隆到Spring容器中的bean(若没有则结束)
44 Iterator propIt =bean.elementIterator();45 while(propIt.hasNext()) {46 Element prop =propIt.next();47
48 //获取propty中的name
49 String propName = prop.attributeValue("name");50 Field f =clazz.getDeclaredField(propName);51
52 //获取propty中的value或者是ref
53 if(f.getType().isPrimitive() || f.getType().equals(String.class)){54 String value = prop.attributeValue("value");55 f.set(o, value);56 //严格时应对propty属性中的value进行分析,存储对应的格式其代码如下:57 //switch(f.getType().getName()) {58 //case "java.lang.String":59 //f.set(o, value);60 //break;61 //case "byte":62 //f.set(o, Byte.parseByte(value));63 //break;64 //case "short":65 //f.set(o, Short.parseShort(value));66 //break;67 //case "int":68 //f.set(o, Integer.parseInt(value));69 //break;70 //case "long":71 //f.set(o, Long.parseLong(value));72 //break;73 //case "char":74 //f.set(o, value.charAt(0));75 //break;76 //case "float":77 //f.set(o, Float.parseFloat(value));78 //break;79 //case "double":80 //f.set(o, Double.parseDouble(value));81 //break;82 //case "boolean":83 //f.set(o, Boolean.parseBoolean(value));84 //break;85 //}
86 } else{87 String ref = prop.attributeValue("ref");88 f.set(o, context.get(ref));89 }90 }91
92 //将bean的名字和对象压进map
93 context.put(id, o);94 }95 } catch(Exception e) {96 e.printStackTrace();97 }98
99 }100
101 /**
102 * 调用这个方法返回bean中的对象103 *@parambeanId104 *@return
105 */
106 publicObject getBean(String beanId) {107 returncontext.get(beanId);108 }109
110 }
LoginServelet.java
1 packagecom.hxz.spring01.servlet;2
3 importcom.hxz.spring01.context.MyContext;4 importcom.hxz.spring01.dao.UserDao;5
6 public classLoginServlet {7 publicString serid;8 public intage;9 publicUserDao dao;10
11 public voiddoPost() {12 if(dao.findByUsernameAndPasswd("admin", "123456")){13
14 } else{15 System.out.println("用户名或者密码错误");16 }17 }18
19 public static voidmain(String[] args) {20 MyContext context = new MyContext("beans.xml");21
22 //2、从context中获取dao
23 LoginServlet login = (LoginServlet) context.getBean("loginServlet");24
25 System.out.println(login.serid);26 System.out.println(login.age);27
28 login.doPost();29 }30
31 publicUserDao getDao() {32 returndao;33 }34
35 public voidsetDao(UserDao dao) {36 this.dao =dao;37 }38
39 }
dao里面就相对简单
dao.java
1 packagecom.hxz.spring01.dao;2
3 public classUserDao {4
5 public booleanfindByUsernameAndPasswd(String string, String string2) {6 return false;7 }8
9 }
接下来就要对配置文件xml进行编写
bean.xml
classpath:/org/springframework/beans/factory/xml/spring-beans-4.3.xsd">