一.框架
框架是一些类和接口的集合,它一个半成品,已经对基础的代码进行了封装并提供相应的API,开发者在使用框架时直接调用封装好的api可以省去很多代码编写,从而提高工作效率和开发速度。
二.Spring
2.1.架构的演进:
单一应用架构
当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。
垂直应用架构
当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,提升效率的方法之一是将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。
分布式服务架构
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服 务框架(RPC)是关键。
流动计算架构
当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是 关键。
2.2.spring
2.2.1.核心解释
spring是一个轻量级开源框架。
spring是为了简化企业开发而生的,使得开发变得更加优雅和简洁。
spring是一个IOC和AOP的容器框架。
IOC:控制反转
AOP:面向切面编程
容器:包含并管理应用对象的生命周期,就好比用桶装水一样,spring就是桶,而对象就是水
2.2.2.使用spring的优点
- Spring通过DI、AOP和消除样板式代码来简化企业级Java开发
- Spring框架之外还存在一个构建在核心框架之上的庞大生态圈,它将Spring扩展到不同的领域,如Web服务、REST、移动开发以及NoSQL
- 低侵入式设计,代码的污染极低
- 独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺
- Spring的IoC容器降低了业务对象替换的复杂性,提高了组件之间的解耦
- Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式处理,从而提供了更好的复用
- Spring的ORM和DAO提供了与第三方持久层框架的的良好整合,并简化了底层的数据库访问
- Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部
2.3.IOC(inversion of controller) 控制反转
2.3.1.为什么要学习IOC
创建一个普通的java项目,实现service层调dao层,dao层是可扩展的。
1.UserDao.java
1 package com.zyj.dao; 2 3 /** 4 * @author zyj 5 * @Package com.zyj.dao 6 */ 7 public interface UserDao { 8 public void getUser(); 9 }
2.UserDaoImpl.java
1 package com.zyj.dao.impl; 2 3 import com.zyj.dao.UserDao; 4 5 /** 6 * @author zyj 7 * @Package com.zyj.dao.impl 8 */ 9 public class UserDaoImpl implements UserDao { 10 @Override 11 public void getUser() { 12 System.out.println("查询数据....."); 13 } 14 }
3.UserService.java
package com.zyj.service; /** * @author zyj * @Package com.zyj.service */ public interface UserService { public void getUser(); }
4.UserServiceImpl.java
package com.zyj.service.impl; import com.zyj.dao.UserDao; import com.zyj.dao.impl.UserDaoImpl; import com.zyj.dao.impl.UserDaoMysqlImpl; import com.zyj.service.UserService; /** * @author zyj * @Package com.zyj.service.impl */ public class UserServiceImpl implements UserService { private UserDao ud = new UserDaoImpl(); @Override public void getUser() { ud.getUser(); } }
5.测试类
1 package com.zyj.test; 2 3 import com.zyj.service.UserService; 4 import com.zyj.service.impl.UserServiceImpl; 5 6 /** 7 * @author zyj 8 * @Package com.zyj.test 9 */ 10 public class MyTest { 11 public static void main(String[] args) { 12 UserService us = new UserServiceImpl(); 13 us.getUser(); 14 } 15 }
6.运行
7.如果此时要新增dao,例如新增UserDaoMysqlImpl.java,则对应的UserServiceImpl势必要改动
1 package com.zyj.service.impl; 2 3 import com.zyj.dao.UserDao; 4 import com.zyj.dao.impl.UserDaoImpl; 5 import com.zyj.dao.impl.UserDaoMysqlImpl; 6 import com.zyj.service.UserService; 7 8 /** 9 * @author zyj 10 * @Package com.zyj.service.impl 11 */ 12 public class UserServiceImpl implements UserService { 13 // private UserDao ud = new UserDaoImpl(); 14 private UserDao ud = new UserDaoMysqlImpl(); 15 @Override 16 public void getUser() { 17 ud.getUser(); 18 } 19 }
8.如果项目需要,还要新增dao,例如新增UserDaoOracleImpl.java,则UserServiceDao势必还要修改,如果项目大的话会造成很大的工作量。很显然这种方式已经不适用。可以采用如下的方式。
修改UserServiceImpl.java
1 package com.zyj.service.impl; 2 3 import com.zyj.dao.UserDao; 4 import com.zyj.dao.impl.UserDaoImpl; 5 import com.zyj.dao.impl.UserDaoMysqlImpl; 6 import com.zyj.service.UserService; 7 8 /** 9 * @author zyj 10 * @Package com.zyj.service.impl 11 */ 12 public class UserServiceImpl implements UserService { 13 // private UserDao ud = new UserDaoImpl(); 14 // private UserDao ud = new UserDaoMysqlImpl(); 15 private UserDao ud; 16 public void setUserDao(UserDao userDao){ 17 this.ud = userDao; 18 } 19 @Override 20 public void getUser() { 21 ud.getUser(); 22 } 23 }
9.在测试类中,new出来UserDaoOracleImpl类对象,然后调UserServiceImpl类的setUerDao方法的方式来创建对象,MyTest.java修改如下:
1 package com.zyj.test; 2 3 import com.zyj.dao.UserDao; 4 import com.zyj.dao.impl.UserDaoOracleImpl; 5 import com.zyj.service.UserService; 6 import com.zyj.service.impl.UserServiceImpl; 7 8 /** 9 * @author zyj 10 * @Package com.zyj.test 11 */ 12 public class MyTest { 13 public static void main(String[] args) { 14 UserServiceImpl us = new UserServiceImpl(); 15 UserDao ud = new UserDaoOracleImpl(); 16 us.setUserDao(ud); 17 us.getUser(); 18 } 19 }
10.运行
总结:一言以蔽之。从上面的代码中我们可以看到解耦(降低程序之间额依赖)的重要性,而使用Spring的IOC可以降低程序之间的耦合性,并提升开发效率,降低成本。
2.3.2.IOC的概念
IOC与大家熟知的依赖注入(DI)同理,这是一个通过依赖注入对象的过程,也就是说,他们所使用的对象,是通过构造函数参数,工厂方法的参数或者是从工厂方法的构造函数或返回值的对象实例设置的属性,然后容器在创建bean时注入这些需要的依赖,这个过程相对于普通创建对象的过程时反向的,bean本身通过直接构造类来控制依赖关系的实例化或位置,或提供诸如服务定位器模式之类的机制。通俗说法:就是我们开发程序时将通过new关键字创建对象的方式交由spring去管理,即spring的IOC(控制反转)。
2.3.3.DI和IOC
很多人把IOC和DI说成一个东西,笼统来说的话是没有问题的,但是本质上还是有所区别的,IOC和DI是从不同的角度描述的同一件事,IOC是从容器的角度描述,而DI是从应用程序的角度来描述,也可以这样说,IOC是设计思想,而DI是具体的实现方式。
2.3.4.IOC基本案例
要求:通过springIOC实现对象的创建,及其属性的赋值
代码实例:
1.Persion.java实体类
1 package com.zyj.entity; 2 3 import org.springframework.core.env.SystemEnvironmentPropertySource; 4 5 /** 6 * @author zyj 7 * @Package com.zyj.entity 8 */ 9 public class Persion { 10 private int id; 11 private String username; 12 private int age; 13 private String address; 14 15 public int getId() { 16 return id; 17 } 18 19 public String getUsername() { 20 return username; 21 } 22 23 public int getAge() { 24 return age; 25 } 26 27 public String getAddress() { 28 return address; 29 } 30 31 public void setId(int id) { 32 this.id = id; 33 } 34 35 public void setUsername(String username) { 36 this.username = username; 37 } 38 39 public void setAge(int age) { 40 this.age = age; 41 } 42 43 public void setAddress(String address) { 44 this.address = address; 45 } 46 47 @Override 48 public String toString() { 49 return "persion{" + 50 "id=" + id + 51 ", username='" + username + '\'' + 52 ", age=" + age + 53 ", address='" + address + '\'' + 54 '}'; 55 } 56 public Persion(){ 57 System.out.println("我被创建了......"); 58 } 59 }
2.pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>springIOC_01</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.3.RELEASE</version> </dependency> </dependencies> </project>
3.编写的配置文件ioc.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" xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--bean标签用于创建bean对象,其id属性表示唯一值,class属性表示要实例化对象的绝对地址--> <bean id="persion" class="com.zyj.entity.Persion"> <!--perperty标签用于给属性值赋值,name代表实体的属性名称,value表示实体属性的赋值--> <property name="id" value="1"></property> <property name="username" value="赵亚军"></property> <property name="age" value="18"></property> <property name="address" value="北京北京"></property> </bean> </beans>
4.测试启动类
1 package com.zyj.application; 2 3 import com.zyj.entity.Persion; 4 import org.springframework.context.ApplicationContext; 5 import org.springframework.context.support.ClassPathXmlApplicationContext; 6 7 /** 8 * @author zyj 9 * @Package com.zyj.application 10 */ 11 /* 12 * ????Sping IOC是什么时候创建的对象?? 13 *在读取spring的配置文件的时候就已经创建了java对象 14 * */ 15 public class MyApplication { 16 public static void main(String[] args) { 17 /** 18 * ApplicationContext是IOC容器的入口类,要获取ioc容器中的对象必须常见该类 19 * ClassPathXmlApplicationContext该类是读取spring的xml配置文件的 20 */ 21 ApplicationContext context = new ClassPathXmlApplicationContext("ioc.xml"); 22 //获取ioc容器中的具体对象,需要强制类型转换 23 // Persion persion = (Persion)context.getBean("persion"); 24 //获取ioc容器中的对象,不需要强制类型转换 25 Persion persion = context.getBean("persion",Persion.class); 26 System.out.println(persion); 27 } 28 }
5.执行结果
6.想看下java对象是通过spring什么时候创建的吗.......修改测试启动类MyApplication.java
1 package com.zyj.application; 2 3 import com.zyj.entity.Persion; 4 import org.springframework.context.ApplicationContext; 5 import org.springframework.context.support.ClassPathXmlApplicationContext; 6 7 /** 8 * @author zyj 9 * @Package com.zyj.application 10 */ 11 /* 12 * ????Sping IOC是什么时候创建的对象?? 13 *在读取spring的配置文件的时候就已经创建了java对象 14 * */ 15 public class MyApplication { 16 public static void main(String[] args) { 17 /** 18 * ApplicationContext是IOC容器的入口类,要获取ioc容器中的对象必须常见该类 19 * ClassPathXmlApplicationContext该类是读取spring的xml配置文件的 20 */ 21 ApplicationContext context = new ClassPathXmlApplicationContext("ioc.xml"); 22 //获取ioc容器中的具体对象,需要强制类型转换 23 // Persion persion = (Persion)context.getBean("persion"); 24 //获取ioc容器中的对象,不需要强制类型转换 25 /*Persion persion = context.getBean("persion",Persion.class); 26 System.out.println(persion);*/ 27 } 28 }
7.执行结果:
由此可看出:在读取spring的配置文件,并没有使用该对象的时候,就已经创建完成了对象。
以上~谢谢!