Spring概述
Spring介绍
-
EJB(面向组件编程), jboss,Spring是一个分层的Java SE/EE(web) full-stack(一站式)轻量级开源框架,以 IoC(Inversion Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核。
-
一站式(一条龙,全家桶):Spring可以通过任何javaEE方向的开发支持
-
轻量级:当前的框架对硬件的要求不高,容易上手,容易使用
-
开源
-
无缝连接:整合目前市面上使用javaEE开发技术
-
在java三层架构当中分别提供了相应激素
- 表现层(web层):SpringMVC(框架)
- 业务层(service层):Bean管理(IOC容器)
- 持久层(dao层):JdbcTemplate模板以及提供了ORM模块整合其他优秀的持久层技术
Spring框架的优势(高内聚 低耦合)
- 方便解耦,简化开发:Spring就一个大工厂,可以管理的所有对象的创建和依赖关系维护,交给Spring管理(池子概念)
- AOP编程的支持:可以方便的实现对程序进行权限拦截,日志记录,运行监控
- 声明式事务的支持:通过配置方式完成对事务的管理,无需手动编程
- 整合外边优秀技术:Spring内部提供了各种优秀框架(Hibernate,Mybatis,Quartz javamial 等)的直接支持
- javaEE技术的封装:Spring对javaEE开发当中复杂难用的API(JavaEmail, RMI等)进行封装,降低了这些API的使用难度
程序的耦合和解耦
程序的耦合
- 程序的耦合是程序之间的关联性,也就是多个类的联系是否紧密,多个对象之间的关系是否密切。
- 写程序的目标是:高内聚 低耦合
解决程序耦合
-
编译不依赖,运行时依赖
-
使用工厂模式解耦合
- 在实际开发中可以把三层的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把对象创建出来并存起来。
SpringIOC机制详解
IOC概述及作用
-
IOC简介,设计思想
- SpringIOC:IOC 是 Inversion of Control 的缩写,翻译成“控制反转”,“控制反向”或者“控制倒置”。
- 控制:Spring框架提供了一个容器控制java开发中的对象
- 正转:洗车-->用户主动的去将车交给洗车店玩车个清洗 (没有ioc机制)
- 反转:洗车--> 洗车店的工作人员 上门洗车服务(接收容器给我们的对象内容)
-
IOC作用
- IOC本质上就是一个大工程,大容器。主要作用就是创建和管理对象的依赖关系,削减计算机程序的耦合(解决代码中的依赖关系),提高程序的可拓展性和可维护性
SpringIOC机制详解
- SpringIOC入门案例
Spring基于XML的IOC细节
-
IOC配置文件详解:配置标签书写规范,配置标签的属性
- bean标签:用于配置对象交给Spring来创建
默认情况下会调用类中无参的构造器,如果没有无参构造器,则不能成功创建 - 基本属性:id: Bean实例对象在Spring容器当中的唯一标识
class:Bean的全限定类名
- bean标签:用于配置对象交给Spring来创建
手动实现自己的IOC容器
-
bean类
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/9/16 13:58 */ @Data @NoArgsConstructor @AllArgsConstructor public class Student { private Integer StuId; private String StuName; } import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/9/16 14:00 */ @Data @NoArgsConstructor @AllArgsConstructor public class Teacher { private Integer TeaId; private String TeaName; }
-
spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="student" class="com.offcn.bean.Student"></bean> <bean id="teacher" class="com.offcn.bean.Teacher"></bean> </bea
-
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>om.offcn</groupId> <artifactId>spring02</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.18</version> </dependency> </dependencies> </project>
-
ApplicationContextDao
/** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/9/16 14:43 */ public interface ApplicationContext { public Object getBean(String name); }
-
ClassPathXmlApplicationContext
import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author: ChengLong * @version: 11.0.2 * @datetime: 2021/9/16 14:43 */ public class ClassPathXmlApplicationContext implements ApplicationContext { Map<String,Object> map = new HashMap<>(); public ClassPathXmlApplicationContext(String path) { //解析过程发生在构造器中 /** * 1.构建解析器 * 2.解析指定位置的xml文件 * 3.获取根标签 * 4.获取子标签 * 5.获取子标签的属性 * 6.通过反射生成属性对应对象 * 7.将对象放入集合中 */ try { SAXReader reader =new SAXReader(); //解析配置文件,将文件构成dom对象 Document document = reader.read(path); //根标签 Element rootElement = document.getRootElement(); // System.out.println(rootElement.getName()); List<Element> bean = rootElement.elements("bean"); for (Element one :bean){ String id = one.attributeValue("id"); String aClass = one.attributeValue("class"); //反射 Object instance = Class.forName(aClass).newInstance(); //放入集合 map.put(id,instance); } } catch (Exception e) { e.printStackTrace(); } } @Override public Object getBean(String name) { return map.get(name); } }
Spring管理bean细节
-
bean实例化介绍
- 容器管理对象的详细的过程(new 对象过程)
-
bean实例化方式
- 构造方法的方式
- 静态工厂方式
-
bean作用域
-
bean作用域介绍
-
所谓Bean的作用域其实就是指Spring给创建出的对象的存活范围,在配置文件中通过bean的scope属性指定
-
scope:指对象的作用范围
- 子主题 1
-
-
bean作用域的解析
-
当scope的取值为singleton时,单例
- Bean的实例化个数:1个
- Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例
-
当scope的取值为prototype时,多例
- Bean的实例化个数:多个
- Bean的实例化时机:当调用getBean()方法时实例化Bean
-
-
Spring依赖注入(容器给属性赋值)
依赖注入的介绍
- 依赖注入(Dependency Injection):它是 Spring 框架核心 IOC 的具体实现。
- 依赖:servlet依赖service才能完成自己的功能
- 注入:依赖的service对象,容器给程序进行赋值(在程序的运行期间容器将管理的service的对象加载到servlet程序中)
- 通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。
IOC 解耦只是降低他们的依赖关系,但不会消除。
坐等框架把持久层对象传入业务层
Spring中依赖注入方式
-
构造函数注入
<!-- 构造器注入--> <bean id="person" class="com.offcn.bean.Person"> <constructor-arg name="pid" value="12"></constructor-arg> <constructor-arg name="pname" value="admin"></constructor-arg> <!-- ref:属性的值必须是容器管理的对象--> <constructor-arg name="dog" ref="newdog"></constructor-arg> </bean>
-
setter注入
<!-- 通过对象set方法属性值注入--> <bean id="newperson" class="com.offcn.bean.Person"> <property name="pid" value="11"></property> <property name="pname" value="user"></property> <property name="dog" ref="newdog"></property> </bean>
-
注入集合数据
<!-- 数组注入--> <property name="myStrs"> <array> <value>red</value> <value>green</value> <value>blue</value> </array> </property> <!-- list注入--> <property name="myList"> <list> <ref bean="newdog"></ref> <bean class="com.offcn.bean.Dog"> <property name="did" value="004"></property> <property name="fuColor" value="blue"></property> </bean> </list> </property> <!-- set集合--> <property name="mySet"> <set> <value>张三</value> <value>赵六</value> <value>王五</value> </set> </property> <!-- map集合注入--> <property name="myMap"> <map> <entry> <!-- 键--> <key> <value>a</value> </key> <!-- 值--> <value>李四</value> </entry> <entry> <key> <value>a</value> </key> <value>李四2</value> </entry> </map> </property> <!--props注入--> <property name="myProps"> <props> <prop key="username">root</prop> <prop key="password">123</prop> </props> </property>
Spring配置文件模块化
Spring模块化介绍
- 现在的配置都集中配在了一个applicationContext.xml文件中,当开发人员过多时, 如果所有bean都配 置到同一个配置文件中,会使这个文件巨大,而且也不方便维护。 针对这个问题,Spring提供了多配置文件的方式,也就是所谓的配置文件模块化
Spring模块化配置
-
Spring模块化配置方式一
-
并列的多个配置文件 直接编写多个配置文件,比如说beans1.xml,beans2.xml......, 然后在创建ApplicationContext的时候,直接传入多个配置文件。
ApplicationContext context = new ClassPathXmlApplicationContext("spring-dog.xml","spring-person.xml");
-
-
Spring模块化配置方式二
<import resource="classpath:spring-dog.xml"></import>
- 注意:
同一个xml文件中不能出现相同名称的bean,如果出现会报错
多个xml文件如果出现相同名称的bean,不会报错,但是后加载的会覆盖前加载的bean,所以企业开发中尽 量保证bean的名称是唯一的。
- 注意:
Spring整合JDBC实现用户CRUD
整合思路分析
- Spring提供了ioc容器,管理jdbc操作数据库的过程中需要的数据库连接对象,同时Spring提供了整合jdbc操作数据库的工具类JdbcDaoSupport 和模板工具 JdbcTemplate,在JdbcTemplate中提供了大量的操作数据库的方式供用户使用。所以我们只需要获取模板工具类然后调用方法就可以完成Jdbc的操作了。
pojo
/**
* @author: ChengLong
* @version: 11.0.2
* @datetime: 2021/9/16 20:43
*/
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private Integer p_id;
private String p_name;
}
dao
import com.offcn.pojo.Person;
/**
* @author: ChengLong
* @version: 11.0.2
* @datetime: 2021/9/16 16:38
*/
public interface PersonDao {
public int addPerson(Person person);
}
接口实现
import com.offcn.pojo.Person;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* @author: ChengLong
* @version: 11.0.2
* @datetime: 2021/9/16 16:45
*/
public class PersonDaoImpl implements PersonDao {
//数据库交互方法必须依赖一个对象 jdbcTemplate
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public int addPerson(Person person){
String sql = "insert into person(p_id,p_name) values(?,?)";
int updata = jdbcTemplate.update(sql,person.getP_id(),person.getP_name());
return updata;
}
}
servicedao
import com.offcn.pojo.Person;
/**
* @author: ChengLong
* @version: 11.0.2
* @datetime: 2021/9/16 20:48
*/
public interface PersonService {
public boolean savePerson(Person person);
}
service
import com.offcn.dao.PersonDao;
import com.offcn.pojo.Person;
/**
* @author: ChengLong
* @version: 11.0.2
* @datetime: 2021/9/16 20:48
*/
public class PersonServiceImpl implements PersonService {
private PersonDao personDao;
public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}
@Override
public boolean savePerson(Person person) {
return personDao.addPerson(person)>0;
}
}
spring配置文件
<?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">
<!--管理一切java对象-->
<bean id="service" class="com.offcn.service.PersonServiceImpl">
<property name="personDao" ref="pdao"></property>
</bean>
<!-- dao对象-->
<bean id="pdao" class="com.offcn.dao.PersonDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 操作数据库的工具类,在操作数据库过程中使用数据库连接-->
<constructor-arg name="dataSource" ref="ds"></constructor-arg>
</bean>
<!-- 容器管理的数据源对象-->
<bean id="ds" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="root"></property>
<property name="password" value="1s2h3a4o56789"></property>
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://192.168.196.181:3306/0622db"></property>
</bean>
</beans>
测试
import com.offcn.dao.PersonDao;
import com.offcn.pojo.Person;
import com.offcn.service.PersonService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author: ChengLong
* @version: 11.0.2
* @datetime: 2021/9/16 20:52
*/
public class SpringJdbc {
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring-core.xml");
PersonDao personDao = (PersonDao) context.getBean("pdao");
Person person = new Person();
person.setP_id(12);
person.setP_name("武松");
PersonService personService = (PersonService) context.getBean("service");
boolean b = personService.savePerson(person);
if(b){
}else{
}
}
}