spring:分層的JavaSE/EE應用full-stack輕量級開源框架,以Ioc(反轉控制)和AOP(面相切面編程)爲內核,提供了展示層springMVC和持久層spring JDBC以及業務層事務管理等衆多的企業級應用技術,還能整合開源世界衆多著名的第三方框架和類庫,逐漸成爲使用最多的JavaEE企業應用開源框架。java
優點:mysql
一、方便解耦,簡化開發web
二、AOP編程的支持spring
三、聲明式事務的支持sql
四、方便程序的測試數據庫
五、方便集成各類優秀框架編程
六、下降JavaEE的使用難度數組
七、源碼的經典的學習範例session
程序的耦合:程序鍵的依賴關係,包括類之間的依賴,方法間的依賴。框架
解耦:下降程序間的依賴關係
實際開發中應該作到,編譯期不依賴,運行時才依賴
解決思路:
第一步:使用反射來建立對象,而避免使用new關鍵字
第二步:經過讀取配置文件來獲取要建立的對象全限定類名。
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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="accountDao" class="lianbang.wu.dao.Impl.AccountDaoImpl"></bean> <bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl"></bean> </beans>
二、獲取ioc核心容器,而且根據id獲取對象
ApplicationContext ac = new ClassPathXmlApplicationContext("Bean.xml"); IAccountDao accountDao = ac.getBean("accountDao",IAccountDao.class); IAccountService accountService = ac.getBean("accountService",IAccountService.class);
ApplicationContext的三個經常使用實現類:
一、ClassPathXmlApplicationContext:它能夠加載類路徑下的配置文件,要求配置文件必須在類路徑下,不在的話,加載不了
二、FileSystemXmlApplicationContext:它能夠加載磁盤任意路徑下的配置文件,前提是有訪問權限
三、AnnotationConfigApplicationContext:它是用於讀取註解建立容器的。
ApplicationContext:它在構建核心容器時,建立對象採用的策略是採用當即加載的方式,也就是說,只要一讀取完配置文件立刻就建立配置文件中配置的對象,適用單例對象
BeanFactory:它在構建核心容器時,建立對象採用的策略是採用延遲加載的方式,也就是說,何時根據id獲取對象了,何時才真正的建立對象,適用多例對象
建立Bean的三種方式:
第一種:使用默認構造函數建立
<bean id="accountDao" class="lianbang.wu.dao.Impl.AccountDaoImpl"></bean>
注意:若是類中沒有默認構造函數,則對象沒法建立
第二種:使用普通工廠類中的方法建立對象(使用某個類中的方法建立對象,並存入spring容器)
<bean id="instanceFactory" class="lianbang.wu.factory.InstanceFactory"></bean> <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
第三種:使用工廠中的靜態方法建立對象(使用某個類中的靜態方法建立對象,並存入spring容器)
<bean id="accountService" class="lianbang.wu.factory.StaticFactory" factory-method="getAccountService"></bean>
Bean的做用範圍調整:
bean標籤的scope屬性
做用:用於指定bean的做用範圍
取值:
singleton:單例,默認值
prototype:多例的
request:做用於web應用的請求範圍
session:做用於web應用的會話範圍
global-session:做用於集羣環境的會話範圍,當不是集羣時,它就是session
<bean id="product" class="lianbang.wu.domain.Product" scope="singleton"></bean>
Bean的生命週期
單例對象
出生:當容器建立時,對象出生
活着:只要容器還在,對象一直活着
死亡:容器銷燬,對象消亡
多例對象
出生:當咱們使用對象時,建立
活着:對象只要在使用過程當中就一直活着
死亡:當對象長時間不用,且沒有別的對象引用時,有java的垃圾回收器回收
spring的依賴注入:
做用:維護依賴關係
能注入的數據:
一、基本類型和String
二、其餘bean類型(在配置文件中或者註解配置過的bean)
三、複雜類型/集合類型
注入的方式:
一、使用構造函數提供
在bean標籤的內部,使用標籤constructor-arg
標籤中的屬性:
type:用於指定要注入的數據的數據類型,該數據類型也是構造函數中某個或某些參數的類型
index:用於指定要注入的數據給構造函數中指定索引位置的參數賦值,索引的位置從0開始
name:用於指定給構造函數中指定名稱的參數賦值
value:用於提供基本類型和string類型的數據
ref:用於指定其餘bean類型數據,它指的就是在spring的Ioc核心容器中出現過的bean對象
</bean> <bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl"> <constructor-arg name="name" value="讀者"></constructor-arg> <constructor-arg name="age" value="18"></constructor-arg> <constructor-arg name="birthday" value="now"></constructor-arg> </bean> <bean id="now" class="java.util.Date"></bean>
好處:在獲取bean對象時,注入數據是必須的操做,不然對象沒法建立成功
壞處:改變了bean對象的實例化方式,使咱們在建立對象時,若是用不到這些數據也必須提供。
二、使用set方法提供
在bean標籤的內部,使用property
標籤的屬性:
name:用於指定注入時所調用的set方法名稱
value:用於提供基本類型和String類型的數據
ref:用於指定其餘的bean類型數據。它指的就是在spring的Ioc容器中出現過的bean對象
</bean> <bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl"> <property name="name" value="讀者"></property> <property name="age" value="18"></property> <property name="birthday" value="now"></property> </bean> <bean id="now" class="java.util.Date"></bean>
好處:建立對象時沒有明確的限制,能夠直接使用默認構造函數
壞處:若是有某個成員必須有值,則獲取對象是有可能set方法沒有執行
三、使用註解提供
複雜類型注入(集合,數組,propertise)
一、array,list,set
</bean> <bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl"> <property name="name"> <array>aaa</array> <array>bbb</array> <array>ccc</array> </property> </bean>
注意:只需將property標籤下對應的子標籤改變成對應的類型
二、map
<bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl"> <property name="name"> <map> <entry key="讀者1" value="做品1"></entry> <entry key="讀者2" value="做品2"></entry> </map> </property> </bean>
三、properties
<bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl"> <property name="name"> <props> <prop key="讀者1">做品1</prop> </props> </property> </bean>
常見的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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <context:component-scan base-package="lianbang.wu"></context:component-scan> </beans>
一、用於建立對象的:做用就和xml配置文件中bean標籤實現的功能同樣
做用:把當前類對象存入spring容器中
屬性:value:用於指定bean的id,當咱們不寫時,默認值是當前類名,首字母小寫
@Controller:通常用在表現層
@Service:通常用在業務層
@Repository:通常用在持久層
以上三個註解他們的做用和屬性於Conponent是同樣的,只是爲咱們提供明確的三層使用的註解,使咱們的三層對象更加清晰。
二、用於注入數據的:做用就和xml配置文件中property標籤實現的功能同樣
@Autowired
做用;自動按照類型注入,只要容器中有惟一一個bean對象類型和要注入的變量類型匹配,就能夠注入成功。若是Ioc容器中沒有任何bean類型和要注入的變量類型匹配,則報錯,若是Ioc容器中有多個類型匹配,根據變量名稱再去匹配Ioc容器中對應類型的Id名稱
出現位置:能夠在變量上,也能夠是方法上
細節:在使用註解注入時,set方法就不是必須的了
@Qualifier
做用:按照類中注入的基礎上再按照名稱注入,它在給類成員注入時不能單獨使用必須與Autowired配合使用,可是在給方法參數注入時能夠
屬性:value:用於指定注入bean的id。
@Resource
做用:直接按照bean的id注入,它能夠單獨使用
屬性:name:用於指定bean的id
@value
做用:用於注入基本數據類型和String類型的數據
屬性:value:用於指定數據的值,它可使用spring中時spEl
spEl的寫法:#{表達式}
三、用於改變做用範圍:做用就和在bean標籤中使用scope屬性實現的功能同樣
@Scope
做用:用於指定bean的做用範圍
屬性:value:指定範圍的取值。經常使用:singleton(默認),prototype
四、和生命週期相關:做用就和bean標準中使用init-method和destroy-method的做用同樣
@PreDestroy
做用:用於指定銷燬方法
@PostConstruct
做用:用於指定初始化方法
Ioc的其餘註解:
@Configuration
做用:當前類是一個配置類
@ConponentScan
做用:用於經過註解指定spring在建立容器時要掃描的包
屬性:value:它和basePackages的做用是同樣的,都是用於指定建立容器時要掃描的包。
@Bean
做用:用於把當前方法的返回值做爲bean對象,存入spring的ioc容器中
屬性:name:用於指定Bean的id,默認值是當前方法的名稱
注意:當使用註解配置方法,若是方法有參數,spring框架會去容器中查找有沒有可用bean對象,和Autowired機制同樣。
使用註解配置類:
ApplicationContext ac = new AnnotationConfigApplicationContext(springConfig.class);
@import
做用:用於導入其餘配置類
@propertySource
做用:用於指定properties文件的位置
屬性:value,指定文件的名稱和路徑,classpath,表示類路徑下
Spring整合Junit
第一步:導入spring整合Junit的jar包
第二步:使用Junit提供的一個註解把原有的main方法替換成spring提供的
@Runwith
第三步:告知spring的運行器,spring的ioc建立是基於xml仍是註解的,而且說明位置
@ContextConfiguration
location:指定xml文件的位置,加上classpath關鍵字,表示在類路徑下
classes:指定註解類所在的位置
注意:當咱們使用spring 5.X版本的時候,要求Junit的jar必須是4.12以上
AOP:
概念:面向切面編程,它就是把完美程序重複的代碼抽取出來,在須要執行的時候,使用動態代理技術,在不修改源碼的基礎上,對完美的已有方法進行加強。
相關術語:
Joinpoint:鏈接點:簡單的說就是能夠被加強的方法
Pointcut:切入點:簡單的說就是被加強了的方法
Advice:通知:攔截到joinpoint以後所要作的事情,通知的類型:前置通知,後置通知,異常通知,最終通知,環繞通知。
Introduction:引介:是一種特殊的通知,在不修改代碼的前提下,能夠在運行期爲類動態的添加一些方法。
Target:目標對象:被代理對象
Weaving:把加強應用到目標對象來建立新的代理對象的過程
Proxy:代理:一個類被AOP織入加強後,就產生一個結果代理類
Aspect:切面:切入點和通知的結合
基於XML方式:
一、把切面添加到Ioc容器
<bean id="logger" class="lianbang.wu.utils.Logger"></bean>
二、使用aop:config標籤代表開始AOP的配置
三、使用aop:aspect標籤代表配置切面
id:給切面提供一個惟一標識
ref:是指定通知類bean的id
四、在aop:aspect標籤的內部使用對應標籤來配置通知的類型
aop:before:表示配置前置通知,在切入點方法執行以前執行
method:指定logger類中哪一個方法是前置通知
pointcut:用於指定切入點表達式,該表達式的含義指的是對業務層中哪些方法加強
切入點表達式的寫法:execution(表達式)
表達式:訪問修飾符 返回值 包名.類名.方法名(參數列表)
全通配寫法 * *..*.*(..)
實際開發一般寫法:* 包名.*.*(..)
aop:after-returning:後置通知,在切入點方法執行以後執行
aop:after-throwing:異常通知,在切入點執行產生異常以後執行
aop:after:最終通知,不管切入點方法是否正常執行,它都會在後面執行
aop:around:環繞配置,當配置環繞通知以後,須要在切入點方法中傳入參數,明確調用切入點等等
<aop:config> <aop:aspect id="logAdvice" ref="logger"> <aop:before method="printLog" pointcut="execution(public void lianbang.wu.service.Impl.AccountServiceImpl.saveAccount())"></aop:before> </aop:aspect> </aop:config> </beans>
基於註解方式:
@Component("logger") @Aspect //@EnableAspectJAutoProxy public class Logger { @Pointcut("execution(* lianbang.wu.service.Impl.*.*(..))") private void pt1(){}; @Before("pt1()") public void printLog(){ System.out.println("Logger類中的方法開始記錄日誌。。。"); }
注意:環繞通知必須傳入ProceedingJoinPoint類型參數
@Around("pt1()") public void around(ProceedingJoinPoint joinPoint){ System.out.println("前置通知"); try { joinPoint.proceed(); } catch (Throwable throwable) { throwable.printStackTrace(); } System.out.println("後置通知"); }
jdbcTemplate
做用:用於和數據庫交互,實現對錶的CRUD操做
public class JdbcTemplateDemo { public static void main(String[] args) { //0、準備數據源 DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(); driverManagerDataSource.setDriverClassName("com.mysql.jdbc.Driver"); driverManagerDataSource.setUrl("jdbc:mysql://localhost:3306/eesy"); driverManagerDataSource.setUsername("root"); driverManagerDataSource.setPassword("120609"); //一、建立對象 JdbcTemplate jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(driverManagerDataSource); //二、執行操做 jdbcTemplate.execute("insert into account(id,uid,money)value (5,46,1000)"); } }
補充:能夠將上面2個new出來的對象放入Ioc對象,在進行調用