日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

06_02_Spring 任务一:IOC控制反转

發布時間:2024/3/13 javascript 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 06_02_Spring 任务一:IOC控制反转 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

任務一課程主要內容:

  • spring概念介紹
  • IOC
  • spring快速入門
  • spring相關API介紹
  • Spring配置文件
  • DBUtils
  • spring注解開發
  • spring整合Junit

一 Spring概述

1.1 Spring是什么

Spring是分層的 Java SE/EE應用 full-stack(全棧式) 輕量級開源框架。

提供了表現層 SpringMVC和持久層 Spring JDBC Template以及 業務層 事務管理等眾多的企業級應用技術,還能整合開源世界眾多著名的第三方框架和類庫,逐漸成為使用最多的Java EE 企業應用開源框架。
兩大核心:以 IOC(Inverse Of Control:控制反轉)和 AOP(Aspect Oriented Programming:面向切面編程)為內核。
IOC:吧對象的創建權交給Spring
AOP:在不修改源代碼的情況下,對方法進行增強

1.2 Spring發展歷程

  • EJB
    1997 年,IBM提出了EJB 的思想
    1998 年,SUN制定開發標準規范 EJB1.0
    1999 年,EJB1.1 發布
    2001 年,EJB2.0 發布
    2003 年,EJB2.1 發布
    2006 年,EJB3.0 發布
  • Spring
    Rod Johnson( Spring 之父)
    改變Java世界的大師級人物
    2002年編著《Expert one on one J2EE design and development》
    指出了JavaEE和EJB組件框架中的存在的一些主要缺陷;提出普通java類依賴注入更為簡單的解決方案。
    2004年編著《Expert one-on-one J2EE Development without EJB》闡述了JavaEE開發時不使用EJB的解決方式(Spring 雛形)
    同年4月spring1.0誕生
    2006年10月,發布 Spring2.0
    2009年12月,發布 Spring3.0
    2013年12月,發布 Spring4.0
    2017年9月, 發布最新 Spring5.0 通用版(GA)

1.3 Spring優勢

  • 1)方便解耦,簡化開發
    Spring就是一個容器,可以將所有對象創建和關系維護交給Spring管理 什么是耦合度?
    對象之間的關系,通常說當一個模塊(對象)更改時也需要更改其他模塊(對象),這就是 耦合,耦合度過高會使代碼的維護成本增加。要盡量解耦.
  • 2)AOP編程的支持
    Spring提供面向切面編程,方便實現程序進行權限攔截,運行監控等功能。
  • 3)聲明式事務的支持
    通過配置完成事務的管理,無需手動編程
  • 4)方便測試
    降低JavaEE API的使用 Spring對Junit4支持,可以使用注解測試
  • 5)方便集成各種優秀框架
    不排除各種優秀的開源框架,內部提供了對各種優秀框架的直接支持

備注:

  • 耦合:程序間的依賴關系
  • 解耦:降低程序間的依賴關系
  • 1.4 Spring體系結構

    二 初識IOC

    2.1 概述

    控制反轉(Inverse Of Control) 不是什么技術,而是一種設計思想。它的目的是指導我們設計出更加松耦合的程序。

    控制:在java中指的是對象的控制權限(創建、銷毀)
    反轉:指的是對象控制權由原來 由開發者在類中手動控制 反轉到 由Spring容器控制

    舉個例子:

    • 傳統方式
      之前我們需要一個userDao實例,需要開發者自己手動創建 new UserDao();
    • IOC方式
      現在我們需要一個userDao實例,直接從spring的IOC容器獲得,對象的創建權交給了spring控制

    2.2 自定義IOC容器

    2.2.1 介紹

    需求
    實現service層與dao層代碼解耦合

    步驟分析

  • 創建java項目,導入自定義IOC相關坐標
  • 編寫Dao接口和實現類
  • 編寫Service接口和實現類
  • 編寫測試代碼
  • 2.2.2 實現

    1)創建java項目,導入自定義IOC相關坐標
    pom.xml

    <dependencies><dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.6.1</version></dependency><dependency><groupId>jaxen</groupId><artifactId>jaxen</artifactId><version>1.1.6</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies>

    2)編寫Dao接口和實現類

    com.lagou.dao.IUserDao public interface IUserDao {public void seve();}com.lagou.dao.impl.UserDaoImpl public class UserDaoImpl implements IUserDao {public void seve() {System.out.println("dao被調用了,保存成功。。。");}}

    3)編寫Service接口和實現類

    com.lagou.service.IUserService public interface IUserService {public void save(); }com.lagou.service.impl.UserServiceImpl public class UserServiceImpl implements IUserService {public void save() {//調用dao層方法,傳統方式:存在編譯期依賴:耦合重IUserDao userDao = new UserDaoImpl();userDao.seve();} }

    4)編寫測試代碼

    com.lagou.test.SpringTest public class SpringTest {@Testpublic void test1(){//獲取到業務層對象IUserService userService = new UserServiceImpl();//調用save方法userService.save();} }

    5)問題

    當前service對象和dao對象耦合度太高,而且每次new的都是一個新的對象,導致服務器壓力過大。

    解耦合的原則是編譯期不依賴,而運行期依賴就行了。

    通過反射的方式進行修改,能正常的被調用:

    public void save() throws ClassNotFoundException, IllegalAccessException, InstantiationException {//調用dao層方法,傳統方式:存在編譯期依賴:耦合重//IUserDao userDao = new UserDaoImpl();//反射,在反射中會出現硬編碼問題,使用配置文件來解決,//吧全路徑抽取出來,放在一個配置文件中IUserDao userDao =(IUserDao) Class.forName("com.lagou.dao.impl.UserDaoImpl").newInstance();userDao.seve();}

    改造步驟:

  • 準備一個配置文件:bean.xml
    把所有需要創建對象的信息定義在配置文件中
  • 編寫一個工廠工具類,工廠類中使用dom4j來解析配置文件,獲取到類的全路徑
  • 使用方式生產對應的數量對象,存到map中(自定義IOC容器)
  • 6)編寫beans.xml
    把所有需要創建對象的信息定義在配置文件中
    beans.xml

    <?xml version="1.0" encoding="UTF-8" ?> <beans> <!--id:存放標識 class:存的就是要生成示例的類的全路徑--><bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"></bean> </beans>

    7)編寫BeanFactory工具類
    com.lagou.utils.BeanFactory

    public class BeanFactory {private static Map<String,Object> iocmap= new HashMap<>();//程序啟動時,初始化對象實例static {//1.讀取配置文件InputStream resourceAsStream = BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml");//2.解析xml(dom4j)SAXReader saxReader = new SAXReader();try {Document document = saxReader.read(resourceAsStream);//3.編寫xpath表達式String xpath = "//bean";//4.獲取到所有的bean標簽,List<Element> list = document.selectNodes(xpath);//5.遍歷并使用方式創建對象實例,存到map集合(ioc容器)中for (Element element : list) {String id = element.attributeValue("id");//className : com.lagou.dao.impl.UserDaoImplString className = element.attributeValue("class");//使用反射生成實例對象Object o = Class.forName(className).newInstance();//存到map中 key:id value:oiocmap.put(id,o);}} catch (DocumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}// 獲取指定id的對象實例public static Object getBean(String beanId){Object o = iocmap.get(beanId);return o;} }

    8)修改UserServiceImpl實現類
    com.lagou.service.impl.UserServiceImpl

    public class UserServiceImpl implements IUserService {public void save() throws ClassNotFoundException, IllegalAccessException, InstantiationException {//調用dao層方法,傳統方式:存在編譯期依賴:耦合重//IUserDao userDao = new UserDaoImpl();//反射//IUserDao userDao =(IUserDao) Class.forName("com.lagou.dao.impl.UserDaoImpl").newInstance();IUserDao userDao =(IUserDao) BeanFactory.getBean("userDao");userDao.seve();} }

    2.2.3 知識小結

    其實升級后的BeanFactory就是一個簡單的Spring的IOC容器所具備的功能。
    之前我們需要一個userDao實例,需要開發者自己手動創建 new UserDao();
    現在我們需要一個userdao實例,直接從spring的IOC容器獲得,對象的創建權交給了spring控制

    • 最終目標:代碼解耦合

    三 Spring快速入門

    3.1 介紹

    需求:借助spring的IOC實現service層與dao層代碼解耦合

    步驟分析

  • 創建java項目,導入spring開發基本坐標
  • 編寫Dao接口和實現類
  • 創建spring核心配置文件
  • 在spring配置文件中配置 UserDaoImpl
  • 使用spring相關API獲得Bean實例
  • 3.2 實現

    1)創建java項目:spring_quickstart,導入spring開發基本坐標
    pom.xml

    <dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.5.RELEASE</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies>

    2)編寫Dao接口和實現類

    com.lagou.dao.IUserDao public interface IUserDao {public void save(); }com.lagou.dao.impl.UserDaoImpl public class UserDaoImpl implements IUserDao {public void save() {System.out.println("dao被調用了。。。");} }

    3)創建spring核心配置文件
    applicationContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"></beans>

    4)在spring配置文件中配置 UserDaoImpl
    applicationContext.xml

    <beans ...> <!--在Spring配置文件中配置UserDaoImplid:唯一標識class:類全路徑--><bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"></bean> </beans>

    5)使用spring相關API獲得Bean實例
    com.lagou.test.SpringTest

    import com.lagou.dao.IUserDao; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringTest {public class SpringTest {@Testpublic void test1(){// 獲取到了spring上下問對象,借助上下文對象可以獲取到IOC容器中的bean對象,加載的同時就創建了bean對象存到容器中ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");//使用上下文對象從IOC容器中獲取到了bean對象IUserDao userDao = (IUserDao) classPathXmlApplicationContext.getBean("userDao");//調用方法userDao.save();} }}

    3.3 知識小結

    Spring的開發步驟

  • 導入坐標
  • 創建Bean
  • 創建applicationContext.xml
  • 在配置文件中進行Bean配置
  • 創建ApplicationContext對象,執行getBean
  • 四 Spring相關API

    4.1 API繼承體系介紹

    Spring的API體系異常龐大,我們現在只關注兩個BeanFactory和ApplicationContext,紫色的為接口,中間淺綠色的為中間類,深綠色的為實現類

    4.2 BeanFactory

    BeanFactory是 IOC 容器的核心接口,它定義了IOC的基本功能。

    特點:在第一次調用getBean()方法時,創建指定對象的實例

    @Testpublic void test2(){//核心接口,不會創建bean對象存到容器中BeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));//getBean的時候才真正的創建bean對象IUserDao userDao =(IUserDao) xmlBeanFactory.getBean("userDao");userDao.save();}

    4.3 ApplicationContext

    代表應用上下文對象,可以獲得spring中IOC容器的Bean對象。

    特點:在spring容器啟動時,加載并創建所有對象的實例

    常用實現類

  • ClassPathXmlApplicationContext
    它是從類的根路徑下加載配置文件 推薦使用這種。
  • FileSystemXmlApplicationContext
    它是從磁盤路徑上加載配置文件,配置文件可以在磁盤的任意位置。
  • AnnotationConfigApplicationContext
    當使用注解配置容器對象時,需要使用此類來創建 spring 容器。它用來讀取注解。
  • ApplicationContext app =new ClassPathXmlApplicationContext("applicationContext.xml");

    常用方法

  • Object getBean(String name);
    根據Bean的id從容器中獲得Bean實例,返回是Object,需要強轉。
  • <T> T getBean(Class <T> requiredType);
    根據類型從容器中匹配Bean實例,當容器中相同類型的Bean有多個時,則此方法會報錯。
  • <T> T getBean(String name,Class <T> requiredType);
    根據Bean的id和類型獲得Bean實例,解決容器中相同類型Bean有多個情況。
  • 4.4 知識小結

    ApplicationContext app = new ClasspathXmlApplicationContext("xml文件"); app.getBean("id"); app.getBean(Class);

    五 Spring配置文件

    5.1 Bean標簽基本配置

    <bean id=“” class=“”></bean>

    • 用于配置對象交由Spring來創建。
    • 基本屬性:
      id:Bean實例在Spring容器中的唯一標識
      class:Bean的全限定名
    • 默認情況下它調用的是類中的 無參構造函數,如果沒有無參構造函數則不能創建成功。

    5.2 Bean標簽范圍配置

    <bean id="" class="" scope=""></bean>

    scope屬性指對象的作用范圍(作用域),取值如下:

    取值范圍說明
    singleton默認值,單例的
    prototype多例的
    requestWEB項目中,Spring創建一個Bean的對象,將對象存入到request域中
    sessionWEB項目中,Spring創建一個Bean的對象,將對象存入到session域中
    global sessionWEB項目中,應用在Portlet環境,如果沒有Portlet環境那么globalSession 相當于 session
  • 當scope的取值為singleton時
    Bean的實例化個數:1個
    Bean的實例化時機:當Spring核心文件被加載時,實例化配置的Bean實例
    Bean的生命周期:
    對象創建:當應用加載,創建容器時,對象就被創建了
    對象運行:只要容器在,對象一直活著
    對象銷毀:當應用卸載,銷毀容器時,對象就被銷毀了
  • 當scope的取值為prototype時
    Bean的實例化個數:多個
    Bean的實例化時機:當調用getBean()方法時實例化Bean
    Bean的生命周期:
    對象創建:當使用對象時,創建新的對象實例
    對象運行:只要對象在使用中,就一直活著
    對象銷毀:當對象長時間不用時,被 Java 的垃圾回收器回收了
  • 5.3 Bean生命周期配置

    <bean id=“” class=“” scope=“” init-method=“” destroy-method=“”></bean>

    • init-method:指定類中的初始化方法名稱
    • destroy-method:指定類中銷毀方法名稱

    5.4 Bean實例化三種方式

    • 無參構造方法實例化
    • 工廠靜態方法實例化
    • 工廠普通方法實例化

    5.4.1 無參構造方法實例化

    它會根據默認無參構造方法來創建類對象,如果bean中沒有默認無參構造函數,將會創建失敗

    <bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"/>

    5.4.2 工廠靜態方法實例化

    應用場景
    依賴的jar包中有個A類,A類中有個靜態方法m1,m1方法的返回值是一個B對象。如果我們頻繁使用B對象,此時我們可以將B對象的創建權交給spring的IOC容器,以后我們在使用B對象時,無需調用A類中的m1方法,直接從IOC容器獲得。

    public class StaticFactoryBean {public static UserDao createUserDao() {return new UserDaoImpl();} } <bean id="userDao" class="com.lagou.factory.StaticFactoryBean" factory-method="createUserDao" />

    5.4.3 工廠普通方法實例化

    應用場景
    依賴的jar包中有個A類,A類中有個普通方法m1,m1方法的返回值是一個B對象。如果我們頻繁使用B對象,此時我們可以將B對象的創建權交給spring的IOC容器,以后我們在使用B對象時,無需調用A類中的m1方法,直接從IOC容器獲得.

    public class DynamicFactoryBean {public IUserDao createUserDao(){return new UserDaoImpl();} } <!--方式三:工廠普通方法實例化--><bean id="dynamicFactoryBean" class="com.lagou.factory.DynamicFactoryBean"></bean><bean id="userDao" factory-bean="dynamicFactoryBean" factory-method="createUserDao"></bean>

    5.5 Bean依賴注入概述

    依賴注入 DI(Dependency Injection):它是 Spring 框架核心 IOC 的具體實現。
    在編寫程序時,通過控制反轉,把對象的創建交給了 Spring,但是代碼中不可能出現沒有依賴的情況。IOC 解耦只是降低他們的依賴關系,但不會消除。
    例如:業務層仍會調用持久層的方法。

    那這種業務層和持久層的依賴關系,在使用 Spring 之后,就讓 Spring 來維護了。簡單的說,就是通過框架把持久層對象傳入業務層,而不用我們自己去獲取。

    5.6 Bean依賴注入方式

    依賴注入的方式本質上算是兩種:

  • 構造方法依賴注入
  • set方法依賴注入(P命名空間注入本質上是set方法依賴注入)
  • 5.6.1 構造方法

    在UserServiceImpl中創建有參構造

    com.lagou.service.impl.UserSerivceImpl public class UserSerivceImpl implements IUserService {private IUserDao userDao;//有參構造public UserSerivceImpl(IUserDao userDao) {this.userDao = userDao;}public void save() {//調用dao層的save方法userDao.save();} }

    創建Service接口

    com.lagou.service.IUserService public interface IUserService {public void save(); }

    配置Spring容器調用有參構造時進行注入

    applicationContext.xml<!--方式一:無參構造方法實例化--><bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"></bean><!--配置UserService--><bean id="userService" class="com.lagou.service.impl.UserSerivceImpl"> <!-- <constructor-arg index="0" type="com.lagou.dao.IUserDao" ref="userDao"/>--><constructor-arg name="userDao" ref="userDao"/></bean>

    測試方法:

    @Testpublic void test5(){ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");IUserService userService = (IUserService) classPathXmlApplicationContext.getBean("userService");userService.save();}結果:dao被調用了。。。

    5.6.2 set方法

    在UserServiceImpl中創建set方法

    public class UserSerivceImpl implements IUserService {private IUserDao userDao;public void setUserDao(IUserDao userDao) {this.userDao = userDao;}public void save() {//調用dao層的save方法userDao.save();} }

    配置Spring容器調用set方法進行注入

    <!--方式一:無參構造方法實例化--><bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"></bean><!--配置UserService--><bean id="userService" class="com.lagou.service.impl.UserSerivceImpl"><!--set方法完成依賴注入--><property name="userDao" ref="userDao"/></bean>

    5.6.3 P命名空間注入

    P命名空間注入本質也是set方法注入,但比起上述的set方法注入更加方便,主要體現在配置文件中,如下:
    首先,需要引入P命名空間:

    <?xml version="1.0" encoding="UTF-8"?> <!-- 在beans中寫入xmlns:p="http://www.springframework.org/schema/p" --> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:p="http://www.springframework.org/schema/p"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">

    其次,需要修改注入方式:

    <!--方式一:無參構造方法實例化--><bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"></bean><!--配置UserService--><bean id="userService" class="com.lagou.service.impl.UserSerivceImpl" p:userDao-ref="userDao"></bean>

    5.7 Bean依賴注入的數據類型

    上面操作,都是注入Bean對象,除了對象的引用可以注入,普通數據類型和集合都可以在容器中進行注入。

    注入數據的三種數據類型

  • 普通數據類型
  • 引用數據類型
  • 集合數據類型
  • 其中引用數據類型,此處就不再贅述了,之前的操作都是對UserDao對象的引用進行注入的。下面將以set方法注入為例,演示普通數據類型和集合數據類型的注入。

    5.7.1 注入普通數據類型

    public class UserDaoImpl implements IUserDao {//注入普通數據類型private String username;private Integer age;public void setUsername(String username) {this.username = username;}public void setAge(Integer age) {this.age = age;}public void save() {System.out.println(username);System.out.println(age);System.out.println("dao被調用了。。。");} } <bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"><!--ref:用于引用數據類型的注入,value是普通數據類型的注入--><property name="username" value="子幕"/><property name="age" value="18"/></bean>

    5.7.2 注入集合數據類型

    1)List集合注入
    新建:User類

    com.lagou.domain.User public class User {private String username;private Integer age;public void setUsername(String username) {this.username = username;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "User{" +"username='" + username + '\'' +", age=" + age +'}';} } public class UserDaoImpl implements IUserDao {private String username;private Integer age;//注入集合數據類型private List<Object> list;public void setList(List<Object> list) {this.list = list;}public void setUsername(String username) {this.username = username;}public void setAge(Integer age) {this.age = age;}public void save() {System.out.println(username);System.out.println(age);System.out.println(list);System.out.println("dao被調用了。。。");} } applicationContext.xml<!--配置User對象--><bean id="user" class="com.lagou.domain.User"><property name="username" value="柳瑩"/><property name="age" value="18"/></bean><!--方式一:無參構造方法實例化--><bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"><!--ref:用于引用數據類型的注入,value是普通數據類型的注入--><property name="username" value="子幕"/><property name="age" value="18"/><!--進行集合數據類型的注入--><property name="list"><list><value>aaa</value><ref bean="user"></ref></list></property></bean>

    2)Set集合注入

    public class UserDaoImpl implements UserDao {private Set<Object> set;public void setSet(Set<Object> set) {this.set = set;}public void save() {System.out.println(set);System.out.println("保存成功了...");} } <bean id="user" class="com.lagou.domain.User"><property name="username" value="jack"/><property name="age" value="18"/></bean><bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"><property name="set"><set><value>bbb</value><ref bean="user"></ref></set></property></bean>

    3)Array數組注入

    public class UserDaoImpl implements UserDao {private Object[] array;public void setArray(Object[] array) {this.array = array;}public void save() {System.out.println(Arrays.toString(array));System.out.println("保存成功了...");} } <bean id="user" class="com.lagou.domain.User"><property name="username" value="jack"/><property name="age" value="18"/></bean><bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"><property name="array"><array><value>ccc</value><ref bean="user"></ref></array></property></bean>

    4)Map集合注入

    public class UserDaoImpl implements UserDao {private Map<String, Object> map;public void setMap(Map<String, Object> map) {this.map = map;}public void save() {System.out.println(map);System.out.println("保存成功了...");} } <bean id="user" class="com.lagou.domain.User"><property name="username" value="jack"/><property name="age" value="18"/></bean><bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"><property name="map"><map><entry key="k1" value="ddd"/><entry key="k2" value-ref="user"></entry></map></property></bean>

    5)Properties配置注入

    5.8 配置文件模塊化

    實際開發中,Spring的配置內容非常多,這就導致Spring配置很繁雜且體積很大,所以,可以將部分配置拆解到其他配置文件中,也就是所謂的配置文件模塊化。
    拆解方式:
    按層次進行拆分,例如三層架構
    按模塊進行拆分,例如商品模塊
    1)并列的多個配置文件

    ApplicationContext act = new ClassPathXmlApplicationContext("beans1.xml","beans2.xml","...");

    2)主從配置文件(常用)

    <beans><import resource="applicationContext-xxx.xml"/> </beans>

    注意:

    • 同一個xml中不能出現相同名稱的bean,如果出現會報錯
    • 多個xml如果出現相同名稱的bean,不會報錯,但是后加載的會覆蓋前加載的bean

    5.9 知識小結

    Spring的重點配置

    • <bean>標簽:創建對象并放到spring的IOC容器
      id屬性:在容器中Bean實例的唯一標識,不允許重復
      class屬性:要實例化的Bean的全限定名
      scope屬性:Bean的作用范圍,常用是Singleton(默認)和prototype
    • <constructor-arg>標簽:屬性注入
      name屬性:屬性名稱
      value屬性:注入的普通屬性值
      ref屬性:注入的對象引用值
    • <property>標簽:屬性注入
      name屬性:屬性名稱
      value屬性:注入的普通屬性值
      ref屬性:注入的對象引用值
    • <list> <set> <array> <map> <props>
    • <import>標簽:導入其他的Spring的配置分文件

    六 DbUtils(IOC實戰)

    6.1 DbUtils是什么?

    DbUtils是Apache的一款用于簡化Dao代碼的工具類,它底層封裝了JDBC技術。
    核心對象

    QueryRunner queryRunner = new QueryRunner(DataSource dataSource);

    核心方法

    • int update(); 執行增、刪、改語句
    • T query(); 執行查詢語句
      ResultSetHandler<T> 這是一個接口,主要作用是將數據庫返回的記錄封裝到實體對象

    舉個栗子
    查詢數據庫所有賬戶信息到Account實體中

    public class DbUtilsTest {@Testpublic void findAllTest() throws Exception {//創建DBUtils工具類,傳入連接池QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource()); // 編寫sqlString sql = "select * from account";// 執行sqlList<Account> list = queryRunner.query(sql, new BeanListHandler<Account>(Account.class));//打印結果for (Account account : list) {System.out.println(account);}} }

    6.2 Spring的xml整合DbUtils

    6.2.1 介紹

    需求
    基于Spring的xml配置實現賬戶的CRUD案例
    步驟分析

  • 準備數據庫環境
  • 創建java項目,導入坐標
  • 編寫Account實體類
  • 編寫AccountDao接口和實現類
  • 編寫AccountService接口和實現類
  • 編寫spring核心配置文件
  • 編寫測試代碼
  • 6.2.2 實現

    1)準備數據庫環境

    CREATE DATABASE `spring_db`; USE `spring_db`; CREATE TABLE `account` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT NULL, `money` double DEFAULT NULL, PRIMARY KEY (`id`) ) ; insert into `account`(`id`,`name`,`money`) values (1,'tom',1000), (2,'jerry',1000);

    2)創建java項目,導入坐標

    <dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.9</version></dependency><dependency><groupId>commons-dbutils</groupId><artifactId>commons-dbutils</artifactId><version>1.6</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.5.RELEASE</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies>

    3)編寫Account實體類

    public class Account {private Integer id;private String name;private Double money;}

    4)編寫AccountDao接口和實現類

    public interface AccountDao {public List<Account> findAll();public Account findById(Integer id);public void save(Account account);public void update(Account account);public void delete(Integer id); } public class AccountDaoImpl implements AccountDao {private QueryRunner queryRunner;public void setQueryRunner(QueryRunner queryRunner) {this.queryRunner = queryRunner;}//查詢所有public List<Account> findAll() {//sqlString sql = "select * from account";List<Account> list = null;try {list = queryRunner.query(sql, new BeanListHandler<Account>(Account.class));} catch (SQLException e) {e.printStackTrace();}return list;}//通過id查詢public Account findById(Integer id) {Account query = null;String sql = "select * from account where id=?";try {query = queryRunner.query(sql, new BeanHandler<Account>(Account.class));} catch (SQLException e) {e.printStackTrace();}return query;}//增加public void save(Account account) {String sql = "INSERT INTO account VALUE(null,?,?)";try {int update = queryRunner.update(sql, account.getName(), account.getMoney());System.out.println("account增加成功");} catch (SQLException e) {e.printStackTrace();}}//修改public void update(Account account) {String sql = "update account set name=?,money=? where id=?";try {int update = queryRunner.update(sql, account.getName(), account.getMoney(), account.getId());System.out.println("Account更新成功");} catch (SQLException e) {e.printStackTrace();}}//通過id進行刪除public void delete(Integer id) {String sql ="delete from account where id=?";try {int update = queryRunner.update(sql, id);} catch (SQLException e) {e.printStackTrace();}} }

    5)編寫AccountService接口和實現類

    public interface AccountService {//查詢所有public List<Account> findAll();//通過id進行查詢public Account findById(Integer id);//添加Accountpublic void save(Account account);//更新Accountpublic void update(Account account);//刪除Accountpublic void delete(Integer id); } public class AccountServiceImpl implements AccountService {private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}public List<Account> findAll() {return accountDao.findAll();}public Account findById(Integer id) {return accountDao.findById(id);}public void save(Account account) {accountDao.save(account);}public void update(Account account) {accountDao.update(account);}public void delete(Integer id) {accountDao.delete(id);} }

    6)編寫spring核心配置文件
    applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:p="http://www.springframework.org/schema/p"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--dataSource 數據庫--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:spring_db"/><property name="username" value="root"/><property name="password" value="qwer1234"/></bean><!--queryRunner--><bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner"><constructor-arg name="ds" ref="dataSource"></constructor-arg></bean><!--AccountDao--><bean id="accountDao" class="com.lagou.dao.impl.AccountDaoImpl"><property name="queryRunner" ref="queryRunner"></property></bean><!--AccountService--><bean id="accountService" class="com.lagou.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"></property></bean></beans>

    7)編寫測試代碼

    public class AccountServiecTest {ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");AccountService accountService = (AccountService) classPathXmlApplicationContext.getBean("accountService");//測試添加@Testpublic void testSave(){Account account =new Account();account.setName("lucy");account.setMoney(888d);accountService.save(account);}//測試查詢@Testpublic void testFindById(){Account byId = accountService.findById(3);System.out.println(byId);}//測試查詢所有@Testpublic void testFindAll(){List<Account> all = accountService.findAll();for (Account account : all) {System.out.println(account);}}//測試更新@Testpublic void testUpdate(){Account account = new Account();account.setId(3);account.setName("jack");account.setMoney(999d);accountService.update(account);}//測試更新@Testpublic void testDelete(){accountService.delete(1);} }

    8)抽取jdbc配置文件
    applicationContext.xml加載jdbc.properties配置文件獲得連接信息。
    首先,需要引入context命名空間和約束路徑:

    • 命名空間:
      xmlns:context=“http://www.springframework.org/schema/context”
    • 約束路徑:
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd
    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd "><context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder><!--dataSource 數據庫--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean> </beans>

    6.3 知識小結

    • DataSource的創建權交由Spring容器去完成
    • QueryRunner的創建權交由Spring容器去完成,使用構造方法傳遞DataSource
    • Spring容器加載properties文件
      <context:property-placeholder location=“xx.properties”/>
      <property name=“” value=“${key}”/>

    七 Spring注解開發

    Spring是輕代碼而重配置的框架,配置比較繁重,影響開發效率,所以注解開發是一種趨勢,注解代替xml配置文件可以簡化配置,提高開發效率。

    7.1 Spring常用注解

    7.1.1 介紹

    Spring常用注解主要是替代 <bean> 的配置

    注解說明
    @Component使用在類上用于實例化Bean
    @Controller使用在web層類上用于實例化Bean
    @Service使用在service層類上用于實例化Bean
    @Repository使用在dao層類上用于實例化Bean
    @Autowired使用在字段上用于根據類型依賴注入
    @Qualifier結合@Autowired一起使用,根據名稱進行依賴注入
    @Resource相當于@Autowired+@Qualifier,按照名稱進行注入
    @Value注入普通屬性
    @Scope標注Bean的作用范圍
    @PostConstruct使用在方法上標注該方法是Bean的初始化方法
    @PreDestroy使用在方法上標注該方法是Bean的銷毀方法

    說明:
    JDK11以后完全移除了javax擴展導致不能使用@resource注解

    需要maven引入依賴 <dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version></dependency>

    注意注解開發需要配置組件掃描

    使用注解進行開發時,需要在applicationContext.xml中配置組件掃描,作用是指定哪個包及其子包下的Bean需要進行掃描以便識別使用注解配置的類、字段和方法。

    <!--注解的組件掃描--> <context:component-scan base-package="com.lagou"></context:component-scan>

    7.1.2 實現

    1)Bean實例化(IOC)

    <bean id="userDao" class="com.lagou.dao.impl.UserDaoImpl"></bean>

    使用@Compont或@Repository標識UserDaoImpl需要Spring進行實例化。

    // @Component(value = "userDao")@Repository// 如果沒有寫value屬性值,Bean的id為:類名首字母小寫public class UserDaoImpl implements UserDao {}

    2)屬性依賴注入(DI)

    <bean id="userService" class="com.lagou.service.impl.UserServiceImpl"> <property name="userDao" ref="userDaoImpl"/> </bean>

    使用@Autowired或者@Autowired+@Qulifier或者@Resource進行userDao的注入

    @Servicepublic class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;//<property name="userDao" ref="userDaoImpl"/>//@Autowired//@Qualifier("userDaoImpl")//@Resource(name = "userDaoImpl")public void setUserDao(UserDao userDao) {this.userDao = userDao;}}

    3)@Value
    使用@Value進行字符串的注入,結合SPEL表達式獲得配置參數

    @Service public class UserServiceImpl implements UserService {@Value("注入普通數據")private String str;@Value("${jdbc.driver}")private String driver; }

    4)@Scope

    <bean scope=""/>

    使用@Scope標注Bean的范圍

    @Service @Scope("singleton") public class UserServiceImpl implements UserService { }

    5)Bean生命周期

    <bean init-method="init" destroy-method="destory" />

    使用@PostConstruct標注初始化方法,使用@PreDestroy標注銷毀方法

    @PostConstruct public void init(){ System.out.println("初始化方法...."); }@PreDestroy public void destroy(){ System.out.println("銷毀方法....."); }

    7.2 Spring常用注解整合DbUtils

    步驟分析

  • 拷貝xml配置項目,改為注解配置項目
  • 修改AccountDaoImpl實現類
  • 修改AccountServiceImpl實現類
  • 修改spring核心配置文件
  • 編寫測試代碼
  • 1)拷貝xml配置項目,改為常用注解配置項目

  • 新建spring_dbutils_anno
  • 復制java下的com所有文件
  • 復制resources下的xml文件
  • 復制pom.xml中的dependencies
  • 2)修改AccountDaoImpl實現類

    @Repository //相當于配置了bean標簽 public class AccountDaoImpl implements AccountDao {@Autowiredprivate QueryRunner queryRunner;... }

    3)修改AccountServiceImpl實現類

    @Service(value = "accountServiceImpl") //相當于配置了bean標簽 value=id屬性 public class AccountServiceImpl implements AccountService {@Autowired //根據類型進行注入 // @Qualifier("accountDao") // @Resource(name = "accountDao")private AccountDao aDao;... }

    4)修改spring核心配置文件

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd "><!--配置注解掃描--><context:component-scan base-package="com.lagou"></context:component-scan><context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder><!--把數據庫連接池交給IOC容器--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--把QueryRunner交給IOC容器--><bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner"><constructor-arg name="ds" ref="dataSource"></constructor-arg></bean> </beans>

    5)編寫測試代碼

    public class AccountServiecTest {ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");AccountService accountService = (AccountService) classPathXmlApplicationContext.getBean("accountServiceImpl");//測試查詢所有@Testpublic void testFindAll() {List<Account> all = accountService.findAll();for (Account account : all) {System.out.println(account);} // classPathXmlApplicationContext.close();} }

    7.3 Spring新注解

    使用上面的注解還不能全部替代xml配置文件,還需要使用注解替代的配置如下:

    • 非自定義的Bean的配置:<bean>
    • 加載properties文件的配置:<context:property-placeholder>
    • 組件掃描的配置:<context:component-scan>
    • 引入其他文件:<import>
    注解說明
    @Configuration用于指定當前類是一個Spring 配置類,當創建容器時會從該類上加載注解
    @Bean使用在方法上,標注將該方法的返回值存儲到 Spring 容器中
    @PropertySource用于加載 properties 文件中的配置
    @ComponentScan用于指定 Spring 在初始化容器時要掃描的包
    @Import用于導入其他配置類

    7.4 Spring純注解整合DbUtils

    步驟分析

  • 編寫Spring核心配置類
  • 編寫數據庫配置信息類
  • 編寫測試代碼
  • 1)編寫Spring核心配置類

    com.lagou.config.SpringConfig/* * 配置文件 * */ @Configuration @ComponentScan("com.lagou") @Import(DataSourceConfig.class) public class SpringConfig {@Beanpublic QueryRunner getQueryRunner(@Autowired DataSource dataSource){QueryRunner queryRunner = new QueryRunner(dataSource);return queryRunner;} }

    2)編寫數據庫配置信息類

    com.lagou.config.DataSourceConfig@PropertySource("classpath:jdbc.properties") public class DataSourceConfig {@Value("${jdbc.driverClassName}")private String driver;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;@Bean("dataSource") //會將當前的返回值放到IOC容器中,如果不起名字那么在IOC中key的值會是方法的名字public DataSource getDataSource(){DruidDataSource druidDataSource = new DruidDataSource();druidDataSource.setDriverClassName(driver);druidDataSource.setUrl(url);druidDataSource.setUsername(username);druidDataSource.setPassword(password);return druidDataSource;} }

    3)編寫測試代碼

    public class AccountServiceTest {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class); AccountService accountService = applicationContext.getBean(AccountService.class); //AccountService accountService = applicationContext.getBean("accountServiceImpl");//測試查詢@Testpublic void testFindById() {Account account = accountService.findById(3); System.out.println(account);}}

    八 Spring整合Junit

    8.1普通Junit測試問題

    在普通的測試類中,需要開發者手動加載配置文件并創建Spring容器,然后通過Spring相關API獲得Bean實例;如果不這么做,那么無法從容器中獲得對象。

    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); AccountService accountService = applicationContext.getBean(AccountService.class);

    我們可以讓SpringJunit負責創建Spring容器來簡化這個操作,開發者可以直接在測試類注入Bean實例;但是需要將配置文件的名稱告訴它。

    8.2 Spring整合Junit

    步驟分析

  • 導入spring集成Junit的坐標
  • 使用@Runwith注解替換原來的運行器
  • 使用@ContextConfiguration指定配置文件或配置類
  • 使用@Autowired注入需要測試的對象
  • 創建測試方法進行測試
  • 1)導入spring集成Junit的坐標
    pom.xml

    <!--此處需要注意的是,spring5 及以上版本要求 junit 的版本必須是 4.12 及以上--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.1.5.RELEASE</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency>

    2)使用@Runwith注解替換原來的運行器
    @RunWhth指定junit的運行環境 SpringJUnit4ClassRunner是spring提供的作為junit運行環境的一個類

    //@RunWhth指定junit的運行環境 SpringJUnit4ClassRunner是spring提供的作為junit運行環境的一個類 @RunWith(SpringJUnit4ClassRunner.class) public class SpringJunitTest { }

    3)使用@ContextConfiguration指定配置文件或配置類

    @RunWith(SpringJUnit4ClassRunner.class)//@RunWhth指定junit的運行環境 SpringJUnit4ClassRunner是spring提供的作為junit運行環境的一個類 //@ContextConfiguration(value = {"classpath:applicationContext.xml"}) 加載spring 核心配置文件 @ContextConfiguration(classes = {SpringConfig.class}) // 加載spring核心配置類 public class SpringJunitTest { }

    4)使用@Autowired注入需要測試的對象

    @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {SpringConfig.class}) public class SpringJunitTest { @Autowired private AccountService accountService; }

    5)創建測試方法進行測試

    @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {SpringConfig.class}) public class SpringJunitTest {@Autowired private AccountService accountService; //測試查詢所有@Testpublic void testFindAll() {List<Account> all = accountService.findAll();for (Account account : all) {System.out.println(account);}} }

    總結

    以上是生活随笔為你收集整理的06_02_Spring 任务一:IOC控制反转的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲av人无码激艳猛片服务器 | 国产成人无码精品 | 琪琪电影午夜理论片八戒八戒 | 久久艹在线观看 | 欧美日韩一区三区 | 久久人人爽人人爽人人片 | 动漫一区二区 | 综合在线观看 | 欧美精品小视频 | 999视频在线观看 | 亚洲精品短视频 | 中文字幕一区二区在线老色批影视 | va欧美| 黄网在线观看视频 | 国产精品毛片一区二区在线看舒淇 | 黄色短视频在线播放 | 成年女人毛片 | 99精品国产一区二区 | 色多多在线视频 | 激情小说亚洲色图 | 18日本xxxxxxxxx95| 奇米精品一区二区三区在线观看一 | 免费裸体美女网站 | 日本亚洲免费 | 纯爱无遮挡h肉动漫在线播放 | 国产无遮挡aaa片爽爽 | 三级影片在线免费观看 | 成人av片免费看 | 一区二区三区网 | 一级视频在线免费观看 | 欧美在线视频免费播放 | 永久免费看mv网站入口78 | www.狠狠插 | 96精品| 黄色片在线免费看 | 综合激情四射 | 成年男女免费视频网站 | 日韩欧美国产另类 | 91精品视频网| 亚洲熟妇av一区二区三区漫画 | 中文乱码人妻一区二区三区视频 | 欧美精品一区二区三区三州 | 好妞色妞国产在线视频 | 亚洲第一在线播放 | 91最新在线视频 | 神马影院午夜伦理片 | 巨胸挤奶视频www网站 | 美女视频毛片 | 欧美 日本 国产 | 五月天激情视频在线观看 | 国产成人aⅴ | 欧美一级一级一级 | 成人精品福利 | 青青草在线视频免费观看 | 亚洲图片欧美激情 | 户外少妇对白啪啪野战 | 窝窝午夜精品一区二区 | 中文人妻av久久人妻18 | 久久免费看视频 | 岛国裸体写真hd在线 | 亚洲综合伊人 | 4438亚洲最大| 97精品超碰一区二区三区 | 草草影院第一页yycc.com | 青青插 | 欧美精品videosex极品 | 欧美视频第一页 | 色五婷婷| 中文字幕在线不卡视频 | 2024国产精品视频 | 亚洲区 欧美区 | 亚洲欧美专区 | 在线不卡av电影 | 美女扒开尿口让男人桶 | 漂亮人妻洗澡被公强 日日躁 | 国产一二三四五区 | 岛国成人在线 | 国产精品久久久久久在线观看 | 国产精品久久午夜夜伦鲁鲁 | 成人免费三级 | 成人婷婷 | 美女精品一区 | 成人av地址 | 日韩91精品 | 亚洲女成人图区 | 国产成人精品999在线观看 | 日本性猛交 | 日本丰满少妇一区二区三区 | 亚洲视频一区二区三区在线观看 | 久久久艹 | 2025国产精品视频 | 久久国产精品久久久久久电车 | 超碰最新上传 | 四虎国产在线 | 日本在线| 亚洲欧美中文字幕 | 国产亚洲精品久久久久四川人 | 青青草视频在线看 | 一区二区三区视频免费观看 |