您好,登錄后才能下訂單哦!
如何理解spring框架,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
spring:分層的JavaSE/EE應用full-stack輕量級開源框架,以Ioc(反轉控制)和AOP(面相切面編程)為內核,提供了展現層springMVC和持久層spring JDBC以及業務層事務管理等眾多的企業級應用技術,還能整合開源世界眾多著名的第三方框架和類庫,逐漸成為使用最多的JavaEE企業應用開源框架。
優勢:
1、方便解耦,簡化開發
2、AOP編程的支持
3、聲明式事務的支持
4、方便程序的測試
5、方便集成各種優秀框架
6、降低JavaEE的使用難度
7、源碼的經典的學習范例
程序的耦合:程序鍵的依賴關系,包括類之間的依賴,方法間的依賴。
解耦:降低程序間的依賴關系
實際開發中應該做到,編譯期不依賴,運行時才依賴
解決思路:
第一步:使用反射來創建對象,而避免使用new關鍵字
第二步:通過讀取配置文件來獲取要創建的對象全限定類名。
Ioc:
概念:控制反轉,把創建對象的權利交給框架,是框架的重要特征,并非面向對象的專用術語。它包括依賴注入和依賴查找。
作用:削減計算機程序的耦合,解除我們代碼中的依賴關系。
使用:
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核心容器,并且根據id獲取對象
ApplicationContext ac = new ClassPathXmlApplicationContext("Bean.xml"); IAccountDao accountDao = ac.getBean("accountDao",IAccountDao.class); IAccountService accountService = ac.getBean("accountService",IAccountService.class);
ApplicationContext的三個常用實現類:
1、ClassPathXmlApplicationContext:它可以加載類路徑下的配置文件,要求配置文件必須在類路徑下,不在的話,加載不了
2、FileSystemXmlApplicationContext:它可以加載磁盤任意路徑下的配置文件,前提是有訪問權限
3、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的依賴注入:
作用:維護依賴關系
能注入的數據:
1、基本類型和String
2、其他bean類型(在配置文件中或者注解配置過的bean)
3、復雜類型/集合類型
注入的方式:
1、使用構造函數提供
在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對象的實例化方式,使我們在創建對象時,如果用不到這些數據也必須提供。
2、使用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方法沒有執行
3、使用注解提供
復雜類型注入(集合,數組,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標簽下對應的子標簽改變成對應的類型
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>
常見的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>
1、用于創建對象的:作用就和xml配置文件中bean標簽實現的功能一樣
@Component
作用:把當前類對象存入spring容器中
屬性:value:用于指定bean的id,當我們不寫時,默認值是當前類名,首字母小寫
@Controller:一般用在表現層
@Service:一般用在業務層
@Repository:一般用在持久層
以上三個注解他們的作用和屬性于Conponent是一樣的,只是為我們提供明確的三層使用的注解,使我們的三層對象更加清晰。
2、用于注入數據的:作用就和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的寫法:#{表達式}
3、用于改變作用范圍:作用就和在bean標簽中使用scope屬性實現的功能一樣
@Scope
作用:用于指定bean的作用范圍
屬性:value:指定范圍的取值。常用:singleton(默認),prototype
4、和生命周期相關:作用就和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方式:
1、把切面添加到Ioc容器
<bean id="logger" class="lianbang.wu.utils.Logger"></bean>
2、使用aop:config標簽表明開始AOP的配置
3、使用aop:aspect標簽表明配置切面
id:給切面提供一個唯一標識
ref:是指定通知類bean的id
4、在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"); //1、創建對象 JdbcTemplate jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(driverManagerDataSource); //2、執行操作 jdbcTemplate.execute("insert into account(id,uid,money)value (5,46,1000)"); } }
補充:可以將上面2個new出來的對象放入Ioc對象,在進行調用
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。