您好,登錄后才能下訂單哦!
如何理解spring框架,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。
spring:分層的JavaSE/EE應(yīng)用full-stack輕量級(jí)開(kāi)源框架,以Ioc(反轉(zhuǎn)控制)和AOP(面相切面編程)為內(nèi)核,提供了展現(xiàn)層springMVC和持久層spring JDBC以及業(yè)務(wù)層事務(wù)管理等眾多的企業(yè)級(jí)應(yīng)用技術(shù),還能整合開(kāi)源世界眾多著名的第三方框架和類庫(kù),逐漸成為使用最多的JavaEE企業(yè)應(yīng)用開(kāi)源框架。
優(yōu)勢(shì):
1、方便解耦,簡(jiǎn)化開(kāi)發(fā)
2、AOP編程的支持
3、聲明式事務(wù)的支持
4、方便程序的測(cè)試
5、方便集成各種優(yōu)秀框架
6、降低JavaEE的使用難度
7、源碼的經(jīng)典的學(xué)習(xí)范例
程序的耦合:程序鍵的依賴關(guān)系,包括類之間的依賴,方法間的依賴。
解耦:降低程序間的依賴關(guān)系
實(shí)際開(kāi)發(fā)中應(yīng)該做到,編譯期不依賴,運(yùn)行時(shí)才依賴
解決思路:
第一步:使用反射來(lái)創(chuàng)建對(duì)象,而避免使用new關(guān)鍵字
第二步:通過(guò)讀取配置文件來(lái)獲取要?jiǎng)?chuàng)建的對(duì)象全限定類名。
Ioc:
概念:控制反轉(zhuǎn),把創(chuàng)建對(duì)象的權(quán)利交給框架,是框架的重要特征,并非面向?qū)ο蟮膶S眯g(shù)語(yǔ)。它包括依賴注入和依賴查找。
作用:削減計(jì)算機(jī)程序的耦合,解除我們代碼中的依賴關(guān)系。
使用:
1、配置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>
2、獲取ioc核心容器,并且根據(jù)id獲取對(duì)象
ApplicationContext ac = new ClassPathXmlApplicationContext("Bean.xml"); IAccountDao accountDao = ac.getBean("accountDao",IAccountDao.class); IAccountService accountService = ac.getBean("accountService",IAccountService.class);
ApplicationContext的三個(gè)常用實(shí)現(xiàn)類:
1、ClassPathXmlApplicationContext:它可以加載類路徑下的配置文件,要求配置文件必須在類路徑下,不在的話,加載不了
2、FileSystemXmlApplicationContext:它可以加載磁盤任意路徑下的配置文件,前提是有訪問(wèn)權(quán)限
3、AnnotationConfigApplicationContext:它是用于讀取注解創(chuàng)建容器的。
ApplicationContext:它在構(gòu)建核心容器時(shí),創(chuàng)建對(duì)象采用的策略是采用立即加載的方式,也就是說(shuō),只要一讀取完配置文件馬上就創(chuàng)建配置文件中配置的對(duì)象,適用單例對(duì)象
BeanFactory:它在構(gòu)建核心容器時(shí),創(chuàng)建對(duì)象采用的策略是采用延遲加載的方式,也就是說(shuō),什么時(shí)候根據(jù)id獲取對(duì)象了,什么時(shí)候才真正的創(chuàng)建對(duì)象,適用多例對(duì)象
創(chuàng)建Bean的三種方式:
第一種:使用默認(rèn)構(gòu)造函數(shù)創(chuàng)建
<bean id="accountDao" class="lianbang.wu.dao.Impl.AccountDaoImpl"></bean>
注意:如果類中沒(méi)有默認(rèn)構(gòu)造函數(shù),則對(duì)象無(wú)法創(chuàng)建
第二種:使用普通工廠類中的方法創(chuàng)建對(duì)象(使用某個(gè)類中的方法創(chuàng)建對(duì)象,并存入spring容器)
<bean id="instanceFactory" class="lianbang.wu.factory.InstanceFactory"></bean> <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
第三種:使用工廠中的靜態(tài)方法創(chuàng)建對(duì)象(使用某個(gè)類中的靜態(tài)方法創(chuàng)建對(duì)象,并存入spring容器)
<bean id="accountService" class="lianbang.wu.factory.StaticFactory" factory-method="getAccountService"></bean>
Bean的作用范圍調(diào)整:
bean標(biāo)簽的scope屬性
作用:用于指定bean的作用范圍
取值:
singleton:?jiǎn)卫?,默認(rèn)值
prototype:多例的
request:作用于web應(yīng)用的請(qǐng)求范圍
session:作用于web應(yīng)用的會(huì)話范圍
global-session:作用于集群環(huán)境的會(huì)話范圍,當(dāng)不是集群時(shí),它就是session
<bean id="product" class="lianbang.wu.domain.Product" scope="singleton"></bean>
Bean的生命周期
單例對(duì)象
出生:當(dāng)容器創(chuàng)建時(shí),對(duì)象出生
活著:只要容器還在,對(duì)象一直活著
死亡:容器銷毀,對(duì)象消亡
多例對(duì)象
出生:當(dāng)我們使用對(duì)象時(shí),創(chuàng)建
活著:對(duì)象只要在使用過(guò)程中就一直活著
死亡:當(dāng)對(duì)象長(zhǎng)時(shí)間不用,且沒(méi)有別的對(duì)象引用時(shí),有java的垃圾回收器回收
spring的依賴注入:
作用:維護(hù)依賴關(guān)系
能注入的數(shù)據(jù):
1、基本類型和String
2、其他bean類型(在配置文件中或者注解配置過(guò)的bean)
3、復(fù)雜類型/集合類型
注入的方式:
1、使用構(gòu)造函數(shù)提供
在bean標(biāo)簽的內(nèi)部,使用標(biāo)簽constructor-arg
標(biāo)簽中的屬性:
type:用于指定要注入的數(shù)據(jù)的數(shù)據(jù)類型,該數(shù)據(jù)類型也是構(gòu)造函數(shù)中某個(gè)或某些參數(shù)的類型
index:用于指定要注入的數(shù)據(jù)給構(gòu)造函數(shù)中指定索引位置的參數(shù)賦值,索引的位置從0開(kāi)始
name:用于指定給構(gòu)造函數(shù)中指定名稱的參數(shù)賦值
value:用于提供基本類型和string類型的數(shù)據(jù)
ref:用于指定其他bean類型數(shù)據(jù),它指的就是在spring的Ioc核心容器中出現(xiàn)過(guò)的bean對(duì)象
</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對(duì)象時(shí),注入數(shù)據(jù)是必須的操作,否則對(duì)象無(wú)法創(chuàng)建成功
壞處:改變了bean對(duì)象的實(shí)例化方式,使我們?cè)趧?chuàng)建對(duì)象時(shí),如果用不到這些數(shù)據(jù)也必須提供。
2、使用set方法提供
在bean標(biāo)簽的內(nèi)部,使用property
標(biāo)簽的屬性:
name:用于指定注入時(shí)所調(diào)用的set方法名稱
value:用于提供基本類型和String類型的數(shù)據(jù)
ref:用于指定其他的bean類型數(shù)據(jù)。它指的就是在spring的Ioc容器中出現(xiàn)過(guò)的bean對(duì)象
</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>
好處:創(chuàng)建對(duì)象時(shí)沒(méi)有明確的限制,可以直接使用默認(rèn)構(gòu)造函數(shù)
壞處:如果有某個(gè)成員必須有值,則獲取對(duì)象是有可能set方法沒(méi)有執(zhí)行
3、使用注解提供
復(fù)雜類型注入(集合,數(shù)組,propertise)
1、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標(biāo)簽下對(duì)應(yīng)的子標(biāo)簽改變成對(duì)應(yīng)的類型
2、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>
3、properties
<bean id="accountService" class="lianbang.wu.service.Impl.AccountServiceImpl"> <property name="name"> <props> <prop key="讀者1">作品1</prop> </props> </property> </bean>
常見(jiàn)的Ioc注解:
注意,使用注解配置時(shí),先要修改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>
1、用于創(chuàng)建對(duì)象的:作用就和xml配置文件中bean標(biāo)簽實(shí)現(xiàn)的功能一樣
@Component
作用:把當(dāng)前類對(duì)象存入spring容器中
屬性:value:用于指定bean的id,當(dāng)我們不寫時(shí),默認(rèn)值是當(dāng)前類名,首字母小寫
@Controller:一般用在表現(xiàn)層
@Service:一般用在業(yè)務(wù)層
@Repository:一般用在持久層
以上三個(gè)注解他們的作用和屬性于Conponent是一樣的,只是為我們提供明確的三層使用的注解,使我們的三層對(duì)象更加清晰。
2、用于注入數(shù)據(jù)的:作用就和xml配置文件中property標(biāo)簽實(shí)現(xiàn)的功能一樣
@Autowired
作用;自動(dòng)按照類型注入,只要容器中有唯一一個(gè)bean對(duì)象類型和要注入的變量類型匹配,就可以注入成功。如果Ioc容器中沒(méi)有任何bean類型和要注入的變量類型匹配,則報(bào)錯(cuò),如果Ioc容器中有多個(gè)類型匹配,根據(jù)變量名稱再去匹配Ioc容器中對(duì)應(yīng)類型的Id名稱
出現(xiàn)位置:可以在變量上,也可以是方法上
細(xì)節(jié):在使用注解注入時(shí),set方法就不是必須的了
@Qualifier
作用:按照類中注入的基礎(chǔ)上再按照名稱注入,它在給類成員注入時(shí)不能單獨(dú)使用必須與Autowired配合使用,但是在給方法參數(shù)注入時(shí)可以
屬性:value:用于指定注入bean的id。
@Resource
作用:直接按照bean的id注入,它可以單獨(dú)使用
屬性:name:用于指定bean的id
@value
作用:用于注入基本數(shù)據(jù)類型和String類型的數(shù)據(jù)
屬性:value:用于指定數(shù)據(jù)的值,它可以使用spring中時(shí)spEl
spEl的寫法:#{表達(dá)式}
3、用于改變作用范圍:作用就和在bean標(biāo)簽中使用scope屬性實(shí)現(xiàn)的功能一樣
@Scope
作用:用于指定bean的作用范圍
屬性:value:指定范圍的取值。常用:singleton(默認(rèn)),prototype
4、和生命周期相關(guān):作用就和bean標(biāo)準(zhǔn)中使用init-method和destroy-method的作用一樣
@PreDestroy
作用:用于指定銷毀方法
@PostConstruct
作用:用于指定初始化方法
Ioc的其他注解:
@Configuration
作用:當(dāng)前類是一個(gè)配置類
@ConponentScan
作用:用于通過(guò)注解指定spring在創(chuàng)建容器時(shí)要掃描的包
屬性:value:它和basePackages的作用是一樣的,都是用于指定創(chuàng)建容器時(shí)要掃描的包。
@Bean
作用:用于把當(dāng)前方法的返回值作為bean對(duì)象,存入spring的ioc容器中
屬性:name:用于指定Bean的id,默認(rèn)值是當(dāng)前方法的名稱
注意:當(dāng)使用注解配置方法,如果方法有參數(shù),spring框架會(huì)去容器中查找有沒(méi)有可用bean對(duì)象,和Autowired機(jī)制一樣。
使用注解配置類:
ApplicationContext ac = new AnnotationConfigApplicationContext(springConfig.class);
@import
作用:用于導(dǎo)入其他配置類
@propertySource
作用:用于指定properties文件的位置
屬性:value,指定文件的名稱和路徑,classpath,表示類路徑下
Spring整合Junit
第一步:導(dǎo)入spring整合Junit的jar包
第二步:使用Junit提供的一個(gè)注解把原有的main方法替換成spring提供的
@Runwith
第三步:告知spring的運(yùn)行器,spring的ioc創(chuàng)建是基于xml還是注解的,并且說(shuō)明位置
@ContextConfiguration
location:指定xml文件的位置,加上classpath關(guān)鍵字,表示在類路徑下
classes:指定注解類所在的位置
注意:當(dāng)我們使用spring 5.X版本的時(shí)候,要求Junit的jar必須是4.12以上
AOP:
概念:面向切面編程,它就是把完美程序重復(fù)的代碼抽取出來(lái),在需要執(zhí)行的時(shí)候,使用動(dòng)態(tài)代理技術(shù),在不修改源碼的基礎(chǔ)上,對(duì)完美的已有方法進(jìn)行增強(qiáng)。
相關(guān)術(shù)語(yǔ):
Joinpoint:連接點(diǎn):簡(jiǎn)單的說(shuō)就是可以被增強(qiáng)的方法
Pointcut:切入點(diǎn):簡(jiǎn)單的說(shuō)就是被增強(qiáng)了的方法
Advice:通知:攔截到j(luò)oinpoint之后所要做的事情,通知的類型:前置通知,后置通知,異常通知,最終通知,環(huán)繞通知。
Introduction:引介:是一種特殊的通知,在不修改代碼的前提下,可以在運(yùn)行期為類動(dòng)態(tài)的添加一些方法。
Target:目標(biāo)對(duì)象:被代理對(duì)象
Weaving:把增強(qiáng)應(yīng)用到目標(biāo)對(duì)象來(lái)創(chuàng)建新的代理對(duì)象的過(guò)程
Proxy:代理:一個(gè)類被AOP織入增強(qiáng)后,就產(chǎn)生一個(gè)結(jié)果代理類
Aspect:切面:切入點(diǎn)和通知的結(jié)合
基于XML方式:
1、把切面添加到Ioc容器
<bean id="logger" class="lianbang.wu.utils.Logger"></bean>
2、使用aop:config標(biāo)簽表明開(kāi)始AOP的配置
3、使用aop:aspect標(biāo)簽表明配置切面
id:給切面提供一個(gè)唯一標(biāo)識(shí)
ref:是指定通知類bean的id
4、在aop:aspect標(biāo)簽的內(nèi)部使用對(duì)應(yīng)標(biāo)簽來(lái)配置通知的類型
aop:before:表示配置前置通知,在切入點(diǎn)方法執(zhí)行之前執(zhí)行
method:指定logger類中哪個(gè)方法是前置通知
pointcut:用于指定切入點(diǎn)表達(dá)式,該表達(dá)式的含義指的是對(duì)業(yè)務(wù)層中哪些方法增強(qiáng)
切入點(diǎn)表達(dá)式的寫法:execution(表達(dá)式)
表達(dá)式:訪問(wèn)修飾符 返回值 包名.類名.方法名(參數(shù)列表)
全通配寫法 * *..*.*(..)
實(shí)際開(kāi)發(fā)通常寫法:* 包名.*.*(..)
aop:after-returning:后置通知,在切入點(diǎn)方法執(zhí)行之后執(zhí)行
aop:after-throwing:異常通知,在切入點(diǎn)執(zhí)行產(chǎn)生異常之后執(zhí)行
aop:after:最終通知,無(wú)論切入點(diǎn)方法是否正常執(zhí)行,它都會(huì)在后面執(zhí)行
aop:around:環(huán)繞配置,當(dāng)配置環(huán)繞通知之后,需要在切入點(diǎn)方法中傳入?yún)?shù),明確調(diào)用切入點(diǎn)等等
<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類中的方法開(kāi)始記錄日志。。。"); }
注意:環(huán)繞通知必須傳入ProceedingJoinPoint類型參數(shù)
@Around("pt1()") public void around(ProceedingJoinPoint joinPoint){ System.out.println("前置通知"); try { joinPoint.proceed(); } catch (Throwable throwable) { throwable.printStackTrace(); } System.out.println("后置通知"); }
jdbcTemplate
作用:用于和數(shù)據(jù)庫(kù)交互,實(shí)現(xiàn)對(duì)表的CRUD操作
public class JdbcTemplateDemo { public static void main(String[] args) { //0、準(zhǔn)備數(shù)據(jù)源 DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(); driverManagerDataSource.setDriverClassName("com.mysql.jdbc.Driver"); driverManagerDataSource.setUrl("jdbc:mysql://localhost:3306/eesy"); driverManagerDataSource.setUsername("root"); driverManagerDataSource.setPassword("120609"); //1、創(chuàng)建對(duì)象 JdbcTemplate jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(driverManagerDataSource); //2、執(zhí)行操作 jdbcTemplate.execute("insert into account(id,uid,money)value (5,46,1000)"); } }
補(bǔ)充:可以將上面2個(gè)new出來(lái)的對(duì)象放入Ioc對(duì)象,在進(jìn)行調(diào)用
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。