33 _ 腦裂:一次奇怪的資料丟失
阿新 • • 發佈:2021-09-13
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{
}
}
}