javascript
SSM三大框架Spring
一、三大框架基本結(jié)構(gòu)
1.為什么需要框架
說明: 如果生產(chǎn)環(huán)境下的項(xiàng)目,都是從頭(從底層寫起)開發(fā),難度太大了,并且開發(fā)的效率極其低下. 所以為了讓項(xiàng)目快速的上線部署. 將某些特定的功能.進(jìn)行了高級(jí)的封裝. 那么我們?nèi)绻枰褂梅庋b后的API.,則必須按照人家的要求編碼
2.框架的分類:
1.Spring框架:整個(gè)框架中負(fù)責(zé)“宏觀調(diào)控”的(主導(dǎo)),負(fù)責(zé)整合其它的第三方的框架
2.SpringMVC框架:主要負(fù)責(zé)實(shí)現(xiàn)前后端數(shù)據(jù)的交互
3.Mybatis框架/MybatisPlus框架:持久層框架,簡化了JDBC操作數(shù)據(jù)庫的方式,提高效率
4.SpringBoot框架/工具:SpringBoo采用了一種更加簡化的方式封裝了之前的框架,讓程序變得更加簡單
3.框架調(diào)用流程圖
?二、Spring框架講解
1.Spring介紹
Spring框架是一個(gè)開放源代碼的J2EE應(yīng)用程序框架,由Rod Johnson發(fā)起,是針對bean的生命周期進(jìn)行管理的輕量級(jí)容器(lightweight container)。
Spring解決了開發(fā)者在J2EE開發(fā)中遇到的許多常見的問題,提供了功能強(qiáng)大IOC、AOP及Web MVC等功能。Spring可以單獨(dú)應(yīng)用于構(gòu)筑應(yīng)用程序,也可以和Struts、Webwork、Tapestry等眾多Web框架組合使用,并且可以與 Swing等桌面應(yīng)用程序AP組合。因此, Spring不僅僅能應(yīng)用于JEE應(yīng)用程序之中,也可以應(yīng)用于桌面應(yīng)用程序以及小應(yīng)用程序之中。Spring框架主要由七部分組成,分別是 Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring Web和 Spring Web MVC。
小結(jié):Spring框架時(shí)針對bean的生命周期進(jìn)行管理的輕量級(jí)容器。其中核心技術(shù)是IOC、AOP
2.Spring-IOC
1.IOC介紹
Ioc全稱Inversion of Control,即“控制反轉(zhuǎn)”,這是一種設(shè)計(jì)思想。對象創(chuàng)建的權(quán)利由Spring框架完成。由容器管理對象的生命周期。
?小結(jié):
①原來的對象的創(chuàng)建都是由用戶自己手動(dòng)創(chuàng)建,這樣的方式耦合性 高,如果類發(fā)生變化,則代碼都得變。
②現(xiàn)在所有的對象都交給spring容器管理,用戶無需關(guān)心對象是如何實(shí)例化,容器負(fù)責(zé)對象的注入即可,?以后幾乎不用修改任何代碼,?降低了代碼的耦合性。
2.創(chuàng)建User類
package com.jt.demo;public class User {public void say(){System.out.println("我是User對象,被spring容器管理");} }3.編輯spring.xml配置文件
說明:由于需要使用spring的框架,所以需要準(zhǔn)備spring的配置文件
在resources文件夾下創(chuàng)建spring.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 http://www.springframework.org/schema/beans/spring-beans.xsd"><!--知識(shí)點(diǎn)講解:該配置文件作用是管理對象術(shù)語: bean 被spring容器管理的對象稱之為bean屬性說明:id:是spring容器中對象的唯一標(biāo)識(shí)符,不能重復(fù)class:對象的全路徑--><bean id="user" class="com.jt.demo.User"></bean> </beans>4.編輯test測試類
package com.jt;import com.jt.demo.User; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestSpring {@Testpublic void TestDemo1(){String resource = "spring.xml";//創(chuàng)建spring容器,并且加載指定的配置文件 ,對象已經(jīng)交給容器管理ApplicationContext context = new ClassPathXmlApplicationContext(resource);//從容器中獲取對象方式1 根據(jù)ID獲取對象User user1 = (User) context.getBean("user");//根據(jù)類型獲取數(shù)據(jù)User user2 = context.getBean(User.class);user1.say();} }?測試結(jié)果:
3.關(guān)于spring容器說明
解釋:spring容器的數(shù)據(jù)結(jié)構(gòu)是Map集合,Map<key,value>,
key=“bean中id的值”,value=“通過反射機(jī)制實(shí)例化的對象”
?4.了解反射源碼
說明:反射的機(jī)制在框架中使用較多,給定類型的路徑就可以獲取其中的對象,但是要求必須有無參構(gòu)造,否則程序運(yùn)行必報(bào)錯(cuò)。
反射方法創(chuàng)建對象時(shí),必然調(diào)用對象的無參構(gòu)造!!! @Testpublic void TestDemo2() throws Exception{User user =(User) Class.forName("com.jt.demo.User").newInstance();user.say();}三、Spring注解開發(fā)
1.編輯User類
package com.jt.demo;public class User {public void say(){System.out.println("使用全注解方式");} }2.編輯配置類
package com.jt.config;import com.jt.demo.User; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;@Configuration //將當(dāng)前類標(biāo)識(shí)為配置類 public class SpringConfig {//xml/**1.xml形式* <bean id="user" class="com.jt.demo.User"></bean>* 2.注解形式* Map集合的機(jī)構(gòu) Map<方法名,方法的返回值>*/@Beanpublic User user(){return new User();//反射機(jī)制}}3.編輯測試類
package com.jt;import com.jt.config.SpringConfig; import com.jt.demo.User; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration;@Configuration public class TestSpring {//利用注解的 方式管理對象@Testpublic void testDemo1(){//1.利用注解方式啟動(dòng)spring容器ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);//2.從容器中獲取對象User user = context.getBean(User.class);//3.對象調(diào)用方法user.say();} }4.關(guān)于IOC總結(jié)
????????1.什么是IOC 由Spring容器管理對象的生命周期,降低代碼耦合性
????????2.xml配置文件管理對象
? ? ? ? ? ? ? ? 1.準(zhǔn)備xxx.xml配置文件
? ? ? ? ? ? ? ? 2.準(zhǔn)備bean標(biāo)簽
? ? ? ? ? ? ? ? 3.spring容器管理對象
? ? ? ? ? ? ? ? ApplicationContext容器頂級(jí)接口
? ? ? ? ? ? ? ? ClassPathXmlApplicationContext 加載配置文件的實(shí)現(xiàn)類對象
? ? ? ? 3.全注解的方式管理對象
? ? ? ? ? ? ? ? 1.準(zhǔn)備配置類@Configuration+@Bean
? ? ? ? ? ? ? ? 2.要求方法 必須有返回值
? ? ? ? ? ? ? ? 3.容器對象
? ? ? ? ? ? ? ? ? ? ? ? ApplicationContext容器頂級(jí)接口
? ? ? ? ? ? ? ? ? ? ? ? AnnotationConfigApplicationContext
? ? ? ? ? ? ? ? ? ? ? ? 萬能語法:根據(jù)當(dāng)前spring的配置規(guī)則,實(shí)例化接口對象,我一般不屑這些代碼,但是可以通過ApplicationContext查找指定的實(shí)現(xiàn)類。
四、工廠模式(重要)
1.關(guān)于對象管理問題說明
問題:任意對象都可以通過new的關(guān)鍵字 實(shí)例化嘛?
答案:不是,抽象類對象,不可以直接實(shí)例化。
2.關(guān)于spring中注解說明
????????1.@Component將當(dāng)前的類,交給spring容器管理,對象的創(chuàng)建是由spring通過反射機(jī)制自動(dòng)創(chuàng)建對象。
????????2.@ComponentScan("com.jt") 指定掃描的包路徑,可以掃描它的子孫包,用在配置類中
?1.編輯User類
package com.jt.demo;import org.springframework.stereotype.Component;@Component//將對象交給Spring容器管理,如果不指定則默認(rèn)就是類名字母小寫 public class User {public void say(){System.out.printf("工廠模式");}}2.編輯配置類
package com.jt.config;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;@Configuration//標(biāo)識(shí)這是一個(gè)配置類 @ComponentScan("com.jt")//給對象指定key的名稱 public class SpringConfig {}3.編輯測試類
@Testpublic void testDemo1(){ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);User user = context.getBean(User.class);user.say();}3.利用工廠模式創(chuàng)建對象
1.業(yè)務(wù)說明
Spring中管理的對象,大部分可以通過new/反射進(jìn)行對象的創(chuàng)建. 但是有些對象由于特殊的原因.不能直接new/實(shí)例化。這時(shí)需要考慮是否可以通過工廠模式實(shí)現(xiàn)。
例如: Calendar 該類是一個(gè)抽象類 所以不能直接實(shí)例化
2.創(chuàng)建工場模式
package com.jt.factory;import org.springframework.beans.factory.FactoryBean; import org.springframework.stereotype.Component;import java.util.Calendar;/*** FactoryBean是spring提供的接口,spring自動(dòng)完成調(diào)用,獲取指定對象** 難點(diǎn)講解:* 1.@Component 標(biāo)識(shí)類 則將該類交給spring容器管理* 2.spring中的FactoryBean的講解 如果spring加載的時(shí)候遇到FactoryBean接口時(shí),* 則會(huì)自動(dòng)執(zhí)行重寫方法* 3.工廠模式說明:* Map<key=calendar,value=calendar對象>* 核心功能:* 1.key:就時(shí)當(dāng)前類型(如果自己編輯注解以注解為準(zhǔn))* 2.value:調(diào)用getObject獲取返回值對象* 將上述的數(shù)據(jù),交給Sprig容器管理* 該功能什么時(shí)候使用:* 1.某些對象不能直接實(shí)例化* 2.整合其他第三方框架對象時(shí),經(jīng)常使用*/ @Component("calendar") //@Component("calendar111") public class CalendarFactory implements FactoryBean<Calendar> {public CalendarFactory(){System.out.println("工廠模式的無參構(gòu)造");}//動(dòng)態(tài)執(zhí)行該方法,獲取返回值對象@Overridepublic Calendar getObject() throws Exception {//利用calendar的工具API,實(shí)現(xiàn)對象的創(chuàng)建return Calendar.getInstance();}@Overridepublic Class<?> getObjectType() {//固定寫法,一般直接xxx。calssreturn Calendar.class;} }3.編輯測試API
@Testpublic void testDemo2(){ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);Calendar calendar = context.getBean(Calendar.class);//Calendar calendar =(Calendar) context.getBean("calendar111");System.out.println("獲取當(dāng)前時(shí)間:"+calendar.getTime());System.out.println("獲取年:"+calendar.getWeekYear());}4.注解復(fù)習(xí)
? ? ? ? 1.@Configuration 標(biāo)識(shí)配置類
? ? ? ? 2.@Bean 將自己方法的返回值交給Spring容器管理
? ? ? ? 3.@component 將該類交給Spring容器管理,通過反射自動(dòng)實(shí)例化對象
? ? ? ? 4.@ComponentScan("com.jt") 包掃描的注解,使Spring注解有效
五、Spring框架講解
?1.單例多例
? 1.關(guān)于單例和多利說明
單例模式:
Spring容器中管理對象,在內(nèi)存中只有一份。
多例模式:
Spring容器中管理對象,在內(nèi)存中有多份。
? 2.測試
編輯User類
package com.jt.demo;public class User {public User(){System.out.println("我是無參構(gòu)造創(chuàng)建對象");}public void say(){System.out.println("測試對象單例還是多例");} }編輯配置類
package com.jt.config;import com.jt.demo.User; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope;@Configuration //標(biāo)識(shí)這是配置類 @ComponentScan("com.jt") public class SpringConfig {@Bean//@Scope("singleton") //默認(rèn)值 單例模式@Scope("prototype") //多例模式public User user(){return new User();}}編輯測試類
@Testpublic void testDemo1() {ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);User user1 = context.getBean(User.class);User user2 = context.getBean(User.class);user1.say();System.out.println(user1 == user2);}? 3.關(guān)于單例多例的測試
????????規(guī)則1:Spring默認(rèn)的測試? ? ??@Scope("singleton")? ? 默認(rèn)值? 單例模式
????????規(guī)則2: @Scope("prototype")? ? ?設(shè)置為多例模式
?2.懶加載機(jī)制
? 1.懶加載說明
說明:如果Spring容器創(chuàng)建,對象立即創(chuàng)建則該加載方式為“立即加載”,? ? ? ? ? ? (容器啟動(dòng)創(chuàng)建)
? ? ? ? ? ?如果Spring容器創(chuàng)建,對象在被使用的時(shí)候才創(chuàng)建,則被稱為“懶加載”。? (用時(shí)創(chuàng)建)
? ? ? ? 注解@Lazy 添加標(biāo)識(shí)改為懶加載
測試說明:主要測試對象中的無參構(gòu)造什么時(shí)候執(zhí)行!
? 2.測試
配置類
package com.jt.config;import com.jt.demo.User; import org.springframework.context.annotation.*;@Configuration //標(biāo)識(shí)這是配置類 @ComponentScan("com.jt") public class SpringConfig {@Bean//@Scope("singleton") //默認(rèn)值 單例模式//@Scope("prototype") //多例模式@Lazy //懶加載public User user(){return new User();}}? 3.多例與懶加載的關(guān)系
說明:只要對象是多例模式,則都是懶加載,在單例模式中控制懶加載才“有效”。
?規(guī)則說明:
? ? ? ? 單例模式:有@Lazy注解時(shí),有效,為懶加載,無@Lazy注解時(shí),為立即加載
????????多例模式:有無@#Lazy無影響,都是懶加載
? 4.關(guān)于Lazy使用場景說明
? ? ? ? 1.服務(wù)器啟動(dòng)時(shí),如果加載太多資源,則必然導(dǎo)致服務(wù)器啟動(dòng)慢,適當(dāng)?shù)膶⒉恢匾馁Y源設(shè)置為懶加載。
? ? ? ? 2.有時(shí)用戶會(huì)需要一些特殊的 “鏈接”,而這些鏈接的創(chuàng)建需要很長的時(shí)間,可以使用懶加載。
?3.Spring生命周期管理
? 1.關(guān)于生命周期說明
說明:一個(gè)對象從創(chuàng)建到消亡,可以劃分為四個(gè)階段,如果需要對程序進(jìn)行干預(yù),則可以通過周期方法進(jìn)行干預(yù)。(回調(diào)函數(shù)/鉤子函數(shù)/接口回調(diào))
生命周期函數(shù)的作用:主要作用可以在各個(gè)時(shí)期對對象進(jìn)行干預(yù)
##2.生命周期函數(shù)方法的使用
1.編輯Person類
package com.jt.demo;import org.springframework.stereotype.Component;import javax.annotation.PostConstruct; import javax.annotation.PreDestroy;@Component //將對象交給spring容器管理 key=Person value:反射對象 public class Person {public Person(){System.out.println("張三出生,資質(zhì)拉滿");}@PostConstruct //在對象創(chuàng)建之后立即調(diào)用 初始化public void init(){System.out.println("張三成為少年奇才");}//業(yè)務(wù)方法public void doWork(){System.out.println("迎娶TXL美人魚!");}@PreDestroy //對象消亡時(shí)調(diào)用public void destroy(){System.out.println("銷毀:奧利給`");} }2.編輯測試類 ,? ?容器對象使用AnnotationConfigApplicationContext類,
容器銷毀:context.close()
@Testpublic void testDemo3Init() {//容器啟動(dòng),對象創(chuàng)建AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);//從容器中獲取對象(要用)Person person = context.getBean(Person.class);person.doWork();//將容器關(guān)閉,銷毀context.close();}? 3.使用注解
? ? ? ? ? ? ? ? @PostConstruct? ? ? ? ? ? ? ? 在對象創(chuàng)建之后調(diào)用(初始化)
? ? ? ? ? ? ? ? @PreDestroy? ? ? ? ? ? ? ? 對象消亡時(shí)調(diào)用(銷毀)
?4.依賴注入(Dependency Injection ,簡稱DI)
? 1.項(xiàng)目結(jié)構(gòu)?
? 2.創(chuàng)建結(jié)構(gòu)
1.創(chuàng)建Cat類 Dog類 User類?
說明:Dog/Cat類進(jìn)行對象的注入功能
? 3.@Autowired注解
功能:可以將Spring容器中的對象,自動(dòng)注入到屬性中
注入方式:
? ? ? ? 1.默認(rèn)按照方式注入,如果注入的屬性是接口,則自動(dòng)注入實(shí)現(xiàn)類。
? ? ? ? 2.按照名稱注入(key),一般條件下不用。
重要前提:如果需要依賴注入,則對象必須交給Spring容器管理。
????????1.編輯Pet接口:
package com.jt.demo;public interface Pet {void hello(); }????????2.編輯Cat類
package com.jt.demo;import org.springframework.stereotype.Component;@Component //將對象交給Spring容器管理 key:Cat value:反射Cat對象 public class Cat implements Pet{@Overridepublic void hello(){System.out.println("貓子叫");} }????????3.編輯User類
package com.jt.demo;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;@Component //將User交給Spring容器管理 public class User {@Autowired //效果:將當(dāng)前接口的實(shí)現(xiàn)類自動(dòng)注入private Pet pet;public void say(){//調(diào)用寵物方法pet.hello();}}????????4.編輯配置類
package com.jt.config;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;@Configuration //標(biāo)識(shí)配置類 @ComponentScan("com.jt") //包掃描 public class SpringConfig { }????????5.編輯測試類
@Testpublic void testDemo1(){AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);User user = context.getBean(User.class);user.say();}????????6.報(bào)錯(cuò)說明:一個(gè)接口一個(gè)只有一個(gè)實(shí)現(xiàn)類,否則Spring程序無法選擇。
? ? ? ? 如果有多個(gè)實(shí)現(xiàn)類,在@Autowired后加@Qualifier("小寫類名")注解,選擇哪個(gè)實(shí)現(xiàn)類加哪個(gè)類名。? ? ? ? ? ? ? ? @Resource(name = "dog")和以上兩個(gè) 結(jié)果相同,但最好不用
?5.MVC設(shè)計(jì)思想
? 1.MVC思想說明
經(jīng)典MVC模式中,M是指業(yè)務(wù)模型,V是指用戶界面,C則是控制器,使用MVC的目的是將M和V的實(shí)現(xiàn)代碼分離,從而使同一個(gè)程序可以使用不同的表現(xiàn)形式。其中,View的定義比較清晰,就是用戶界面。
M:model 業(yè)務(wù)模型
V:view? 用戶界面
C:controller? 控制層
小結(jié):
? ? ? ? 1.MVC是一種設(shè)計(jì)思想,在編碼中降低代碼的耦合性。
? ? ? ? 2.前端專注于開發(fā)頁面view
? ? ? ? 3.后端專注于開發(fā)后端model
? ? ? ? 4.2者通過controller進(jìn)行控制
? 2.層級(jí)代碼結(jié)構(gòu)
說明:MVC設(shè)計(jì)思想,實(shí)現(xiàn)了前端和后端的松耦合。為了很好的實(shí)現(xiàn)MVC設(shè)計(jì)思想,所以后端代碼也應(yīng)該分層。
分層說明:
? ? ? ? 1.控制層? ? ? ? Controller? ? ? ? 與前端頁面交互? ? ? ? ? ? ? ? @Controller
? ? ? ? 2.業(yè)務(wù)層? ? ? ? Service? ? ? ? 編輯業(yè)務(wù)邏輯? ? ? ? ? ? ? ? ? ? ? ??@Service
? ? ? ? 3.持久層? ? ? ? Mapper? ? ? ? 實(shí)現(xiàn)數(shù)據(jù)庫的相關(guān)操作? ? ? ? ? 暫時(shí):@Repository
? 3.創(chuàng)建項(xiàng)目
????????1.編輯Dao層/Mapper層
? ? ? ? 編輯UserMapper接口和實(shí)現(xiàn)類
package com.jt.mapper;//面向接口開發(fā) public interface UserMapper {void addUser(); } package com.jt.mapper;import org.springframework.stereotype.Repository;@Repository //為了讓程序員開發(fā)更有層級(jí)的概念 public class UserMapperImpl implements UserMapper {@Overridepublic void addUser() {System.out.println("新增用戶TXL");} }????????2.編輯Service層
? ? ? ? 編輯UserService接口及實(shí)現(xiàn)類
package com.jt.service;public interface UserService {void addUser(); } package com.jt.service;import com.jt.mapper.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;@Service public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapperr; //默認(rèn)按照類型注入@Overridepublic void addUser() {userMapperr.addUser();} }? ? ? ? 3.編輯Controller層
package com.jt.controller;import com.jt.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller;@Controller public class UserController {@Autowiredprivate UserService userService;public void insert(){userService.addUser();} }? ? ? ? 4.編輯測試類
@Testpublic void testDemoMVC1(){ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);UserController controller = context.getBean(UserController.class);controller.insert();}?6.請談一下對IOC/DI的看法
? ? ? ? 歷史:傳統(tǒng)代碼其中的屬性對象一般都通過new關(guān)鍵字手動(dòng)創(chuàng)建,這樣的代碼耦合性高,不方便擴(kuò)展。
? ? ? ? 功能:
? ? ? ? ? ? ? ? 1.IOC:由Spring容器管理對象的生命周期
? ? ? ? ? ? ? ? 2.使得對象與對象之間的耦合性降低
? ? ? ? ? ? ? ? 3.DI是依賴注入,只有被Spring容器管理的對象才可以被依賴注入,默認(rèn)條件下采用類型注入,如果有特殊需求也可以采用名稱注入@Qualifier("cat")。
? ? ? ? ? ? ? ? 4.Spring中? IOC和DI相互配合? ,可以極大程度上降低耦合性
????????意義:Spring由于采用了IOC/DI的設(shè)計(jì)方式,可以整合其它的第三方框架,使得程序的調(diào)用渾然一體。
?7.@Value注解說明
說明:@Value注解 可以直接為?基本類型 和 String類型賦值
問題:如果像圖中賦值,則耦合性依然很高,不通用
? 1.編輯user.properties
說明:對象中的屬性一般都是業(yè)務(wù)數(shù)據(jù),如果需要為業(yè)務(wù)數(shù)據(jù)賦值,則一般采用properties文件,更加靈活。
位置:在resources下創(chuàng)建user.properties
配置文件的內(nèi)容:
user.id=008 user.name=張三? 2.@Value為屬性賦值
package com.jt.mapper;import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Repository;@Repository //為了讓程序員開發(fā)更有層級(jí)概念 @PropertySource(value = "classpath:/user.properties",encoding = "utf-8") // :/ 代表資源加載路徑 public class UserMapperImpl implements UserMapper{//耦合性,動(dòng)態(tài)賦值//表達(dá)式: 固定寫法${} springel表達(dá)式 取值方式 縮寫spel表達(dá)式//規(guī)則:通過表達(dá)式動(dòng)態(tài)獲取spring容器中的value@Value("${user.id1}")private int id1;@Value("${user.name1}")private String name1;@Overridepublic void addUser() {System.out.println("新增用戶id:"+id1+"新增用戶姓名:"+name1);} }六、代理模式
?1.創(chuàng)建項(xiàng)目
?2.Spring-AOP
? AOP介紹
AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預(yù)編譯方式和運(yùn)行期間動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP是OOP的延續(xù),是軟件開發(fā)中的一個(gè)熱點(diǎn),也是Spring框架中的一個(gè)重要內(nèi)容,是函數(shù)式編程的一種衍生范型。利用AOP可以對業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率。
AOP主要作用: 在不修改原有代碼的條件下 對方法進(jìn)行擴(kuò)展
?3.業(yè)務(wù)層如何控制事務(wù)
事務(wù):可以保證數(shù)據(jù)的原子性、一致性、持久性、隔離性
@Overridepublic void addUser() {try{System.out.println("開啟數(shù)據(jù)庫事務(wù)");System.out.println("新增用戶");System.out.println("提交數(shù)據(jù)庫事務(wù)");}catch (Exception e){System.out.println("事務(wù)回滾");}}? 1.業(yè)務(wù)代碼-問題
? ? ? ? 1.如果有多個(gè)方法,則每個(gè)方法都需要控制事務(wù),代碼重復(fù)率很高
? ? ? ? 2.業(yè)務(wù)層service,應(yīng)該只處理業(yè)務(wù),不要和事務(wù)代碼耦合在一起,否則擴(kuò)展性不好,耦合性高。
如何解決:采用代理機(jī)制解決
?4.代理機(jī)制
? 1.代理模式說明
說明:一般采用代理模式,主要目的就是為了解耦,將公共的通用的方法(功能/業(yè)務(wù))放到代理對象中,由業(yè)務(wù)層專注于業(yè)務(wù)執(zhí)行即可。
? 2.代理特點(diǎn)
? ? ? ? 1.為什么使用代理?因?yàn)樽约?strong>不方便(沒有資源)
? ? ? ? 2.代理作用?? ? ? ? ? ?代理要解決(擴(kuò)展)某些實(shí)際問題
? ? ? ? 3.用戶最終執(zhí)行目標(biāo)方法!
? ?3.動(dòng)態(tài)代理-JDK模式(Spring整合Mybatis用的是JDK代理模式)
? ? ? ? 1.JDK代理的說明
? ? ? ? ? ? ? ? 1.JDK代理模式是java原生提供的AOI,無需導(dǎo)包
? ? ? ? ? ? ? ? 2.JDK代理要求:被代理者必須? 要么是接口要么實(shí)現(xiàn)接口? 接口
? ? ? ? ? ? ? ? 3.靈活:代理對象 應(yīng)該看起來和被代理者一模一樣(方法相同)
? ? ? ? 2.編輯代理類
package com.jt.proxy;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;public class JDKProxy {//傳入target目標(biāo)對象,獲取代理對象//利用代理對象 實(shí)現(xiàn)方法的擴(kuò)展public static Object getProxy(Object target) {//1.獲取類加載器(先得到類型,再得到類加載器)ClassLoader classLoader = target.getClass().getClassLoader();//2.獲取接口的數(shù)組類型Class<?>[] interfaces = target.getClass().getInterfaces();//3.代理對象執(zhí)行方法時(shí)的回調(diào)方法(代理對象調(diào)用方法時(shí),執(zhí)行InvocationHandler)return Proxy.newProxyInstance(classLoader, interfaces, invocationHandler(target));}//要求必須傳遞目標(biāo)對象public static InvocationHandler invocationHandler(Object target) {return new InvocationHandler() {/*** 參數(shù)說明:* 1.proxy代理對象* 2.method執(zhí)行當(dāng)前的目標(biāo)方法* 3.Object[] args 參數(shù)數(shù)組* */@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("事務(wù)開始");//執(zhí)行目標(biāo)方法,獲取目標(biāo)方法的返回值Object result = method.invoke(target, args);System.out.println("事務(wù)提交");return result;}};} }? 4.動(dòng)態(tài)代理-CGLIB代理(SpringBoot默認(rèn)代理機(jī)制)
? ? ? ? 1.CGLIB說明
jdk代理:要求必須有/實(shí)現(xiàn)接口,如果沒有接口,則JDK代理不能正常運(yùn)行
cglib代理:要求被代理者有無接口都可以,代理對象是目標(biāo)對象的子類? 重寫子類方法
? ? ? ? 2.編輯代理類
package com.jt.proxy;import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class CGlibProxy {public static Object getProxy(Object target){//1.創(chuàng)建增強(qiáng)器對象Enhancer enhancer = new Enhancer();//2.設(shè)定父級(jí) 目標(biāo)對象enhancer.setSuperclass(target.getClass());//3.定義回調(diào)的方法 代理對象執(zhí)行目標(biāo)方法時(shí)調(diào)用enhancer.setCallback(getMethodInterceptor(target));//4.創(chuàng)建代理對象return enhancer.create();}public static MethodInterceptor getMethodInterceptor(Object target){return new MethodInterceptor() {@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("事務(wù)開始");Object result = method.invoke(target, objects);System.out.println("事務(wù)提交");return null;}};} }? 5.關(guān)于JDK代理和CGLIB代理總結(jié)
1.JDK要求必須有/實(shí)現(xiàn)接口,cgblib有無接口都可以創(chuàng)建代理對象,代理對象是目標(biāo)對象的子類
2.JDK代理根據(jù)API:Proxy.newProxyInstance(類加載器,接口數(shù)組,invocationHandle接口)
3.CGLIB代理工具API:Enhancer 增強(qiáng)器對象? ? ? 獲取代理對象:enhancer.create()?
?回調(diào)接口:MethodInterceptor接口
4.JDK中必須執(zhí)行目標(biāo)方法:method.invoke(target,args)
? ?CGLIB必須執(zhí)行的目標(biāo)方法:method.invoke(target,args)
5.Spring AOP介紹
? ?1.引入jar包
<!--引入AOPjar包文件--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>? 2.AOP介紹
在軟件業(yè),AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預(yù)編譯方式和運(yùn)行期間動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP是OOP的延續(xù),是軟件開發(fā)中的一個(gè)熱點(diǎn),也是Spring框架中的一個(gè)重要內(nèi)容,是函數(shù)式編程的一種衍生范型。利用AOP可以對業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率。
總結(jié): Spring中的AOP 利用代理對象在不修改源代碼的條件下,對方法進(jìn)行擴(kuò)展。
? 3.AOP中專業(yè)術(shù)語
? ? ? ? 1.連接點(diǎn):用戶可以被擴(kuò)展的方法
? ? ? ? 2.切入點(diǎn):用戶實(shí)際擴(kuò)展的方法
? ? ? ? 3.通知:擴(kuò)展方法的具體體現(xiàn)
? ? ? ? 4.切面:將通知應(yīng)用到切入點(diǎn)過程
? ?4.AOP入門案例
? ? ? ? 1.編輯配置類
package com.jt.config;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration @ComponentScan("com.jt") @EnableAspectJAutoProxy //開啟AOP,啟用切面自動(dòng)注解 public class SpringConfig { }? ? ? ? ?2.編輯切面類1
package com.jt.aop;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component;@Component //將該類交給spring容器管理 @Aspect //定義切面類 public class SpringAOP {/*** 公式: 切面=切入點(diǎn)表達(dá)式 + 停止方法* 切入點(diǎn)表達(dá)式:如果目標(biāo)對象滿足切入點(diǎn)表達(dá)式的判斷* 則spring自動(dòng)為其創(chuàng)建代理對象* 目標(biāo)對象的bean的id:userServiceImpl* 切入點(diǎn)表達(dá)式:@Pointcut* 1.bean("bean的ID")* AOP規(guī)則:如果目標(biāo)對象滿足切入點(diǎn)表達(dá)式,則執(zhí)行通知方法** */@Pointcut("bean(userServiceImpl)")public void pointcut(){}//1.前置通知:在目標(biāo)方法執(zhí)行之前執(zhí)行@Before("pointcut()")public void before(){System.out.println("我是前置通知");}//2.后置通知:在目標(biāo)方法執(zhí)行之后執(zhí)行@AfterReturning("pointcut()")public void afterReturning(){System.out.println("我是后置通知");}//3.異常通知:目標(biāo)方法執(zhí)行報(bào)錯(cuò)時(shí),執(zhí)行該通知@AfterThrowing("pointcut()")public void afterThrow(){System.out.println("我是異常通知");}//4.最終通知:目標(biāo)方法之后都要執(zhí)行的通知@After("pointcut()")public void after(){System.out.println("我是最終通知,都要執(zhí)行");}//5.(重點(diǎn))環(huán)繞通知:在目標(biāo)方法執(zhí)行前后都要執(zhí)行,控制目標(biāo)方法@Around("pointcut()")public Object around(ProceedingJoinPoint joinPoint)throws Throwable{System.out.println("環(huán)繞通知執(zhí)行前");Object result = joinPoint.proceed();System.out.println("環(huán)繞通知執(zhí)行后");return result;}}5.切入點(diǎn)表達(dá)式
? ? ? ? 1.bean標(biāo)簽
說明:根據(jù)bean的ID匹配
? ? ? ? 2.within標(biāo)簽
說明:按照類型匹配,可以使用通配符 * 號(hào)
語法:
? ? ? ? 1.@Pointcut("within(com.jt.service.UserServiceImpl)")? ? ?//攔截UserServiceImpl這個(gè)類
? ? ? ? 2.@Pointcut("within(com.jt.service.*)")? ? //攔截com.jt.service下的所有的類(一個(gè)點(diǎn),攔截所有類)
????????3.@Pointcut("within(com.jt.service..*)")? ? //(兩個(gè)點(diǎn),攔截所有,包括子包里的類)
? ? ? ? 4.@Pointcut("within(com.*.service..*)")? ? ? //com包下的所有包含service包的所有
? ? ? ? 3.execution表達(dá)式
作用: 粒度比較細(xì),可以按照方法參數(shù)進(jìn)行匹配
????????@Pointcut("execution(返回值類型 包名.類名.方法名(參數(shù)列表))")
????????1. 按照類型方法匹配
????????@Pointcut("execution(* com.jt.service.UserServiceImpl.addUser())")
????????2. 要求返回值任意, com.jt.service包下的所有的子孫類中的任意方法的任意參數(shù)要求攔截.
????????@Pointcut("execution(* com.jt.service..*.*(..))")
????????3. 要求返回值任意, com.jt.service包下的所有的子孫類中的add開頭的方法并且參數(shù)1個(gè)是int類型 進(jìn)行攔截
????????@Pointcut("execution(* com.jt.service..*.add*(int))")
? ? ? ? 4.@annotation表達(dá)式
? ? ? ? 1.完成自定義注解Gjh????????????????????????
@Pointcut("@annotation(com.jt.anno.Gjh)") package com.jt.anno;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)//注解運(yùn)行期有效 @Target(ElementType.METHOD) //注解標(biāo)識(shí)方法 public @interface Gjh {String name() default "gjh";int age(); }? ? ? ? 2.完成標(biāo)記注解
給delUser()方法加上自定義注解@Gjh就能加上通知
public class UserServiceImpl implements UserService{@Override@Gjh(age = 23)public void addUser() {System.out.println("新增用戶");//int a = 1/0;}@Gjh(age = 23)@Overridepublic void delUser() {System.out.println("刪除用戶");} }? 6.關(guān)于通知
? ? ? ? 1.關(guān)于AOP通知的用法
第一類:
? ? ? ? 1.@Before通知:目標(biāo)方法執(zhí)行前執(zhí)行
? ? ? ? 2.@AfterReturning通知:目標(biāo)方法執(zhí)行后執(zhí)行
? ? ? ? 3.@AfterThrowing通知:目標(biāo)方法報(bào)錯(cuò)時(shí)執(zhí)行
? ? ? ? 4.@After通知:目標(biāo)方法執(zhí)行之后,最后執(zhí)行????????
????????日志系統(tǒng):可以記錄程序執(zhí)行的各個(gè)過程,為日志提供記錄
第二類:
? ? ? ? 5.@Around環(huán)繞通知,可以控制目標(biāo)方法是否執(zhí)行,環(huán)繞通知可以控制業(yè)務(wù)流轉(zhuǎn)的過程。
? ? ? ? ? ? ? ? 例子:
? ? ? ? ? ? ? ? ? ? ? ? 1.權(quán)限的校驗(yàn)
? ? ? ? ? ? ? ? ? ? ? ? 2.緩存系統(tǒng)
? ? ? ? ? ? ? ? ? ? ? ? 3.異常處理
? ? ? ? 2.通知中常用API? ?
ProceedingJoinPoint 只能用在環(huán)繞通知中
//1.前置通知:在目標(biāo)方法執(zhí)行之前執(zhí)行@Before("pointcut()")public void before(JoinPoint joinPoint){//連接點(diǎn):獲取方法中的數(shù)據(jù)//獲取目標(biāo)對象的類型Class<?> targetClass = joinPoint.getTarget().getClass();//獲取方法名稱String methodName = joinPoint.getSignature().getName();//獲取類名String className = joinPoint.getSignature().getDeclaringTypeName();Object[] objs = joinPoint.getArgs();System.out.println("我是前置通知");System.out.println("類型"+targetClass);System.out.println("方法名稱"+methodName);System.out.println("類名"+className);System.out.println("方法中攜帶的參數(shù)"+ Arrays.toString(objs));}? ? ? ? 3.后置通知
需求:記錄目標(biāo)方法的返回值
說明:通過屬性returning獲取方法的返回值
//2.后置通知:在目標(biāo)方法執(zhí)行之后執(zhí)行//通過returning = "result"屬性,獲取目標(biāo)方法的返回值,當(dāng)作參數(shù)傳給result@AfterReturning(value = "pointcut()",returning = "result")public void afterReturning(Object result){System.out.println("我是后置通知");System.out.println("用戶的返回值為:"+result);}? ? ? ? 4.異常通知
說明:如果用戶執(zhí)行業(yè)務(wù)方法時(shí),報(bào)錯(cuò)了,可以使用異常通知記錄日志
//3.異常通知:目標(biāo)方法執(zhí)行報(bào)錯(cuò)時(shí),執(zhí)行該通知@AfterThrowing(value = "pointcut()",throwing = "exception")public void afterThrow(Exception exception){System.out.println("我是異常通知");System.out.println("獲取異常信息"+exception.getMessage());exception.printStackTrace();//所有異常}? 7.AOP執(zhí)行順序(切面排序)
? ? ? ? @Order(數(shù)字)? 數(shù)字越小越靠前執(zhí)行
編輯AOP類1
package com.jt.aop;import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component;import java.util.Arrays;@Component //將該類交給spring容器管理 @Aspect //定義切面類 @Order(2) //執(zhí)行順序AOP第二個(gè)執(zhí)行,數(shù)字越小越靠前 public class SpringAOP {/*** 公式: 切面=切入點(diǎn)表達(dá)式 + 停止方法* 切入點(diǎn)表達(dá)式:如果目標(biāo)對象滿足切入點(diǎn)表達(dá)式的判斷* 則spring自動(dòng)為其創(chuàng)建代理對象* 目標(biāo)對象的bean的id:userServiceImpl* 切入點(diǎn)表達(dá)式:@Pointcut* 1.bean("bean的ID")* AOP規(guī)則:如果目標(biāo)對象滿足切入點(diǎn)表達(dá)式,則執(zhí)行通知方法** *///@Pointcut("bean(userServiceImpl)")//@Pointcut("within(com.jt.service.UserServiceImpl)")//@Pointcut("within(com.jt.service..*)")//@Pointcut("execution(* com.jt.service.UserServiceImpl.addUser())")//@Pointcut("execution(* com.jt.service..*.*(..))")@Pointcut("@annotation(com.jt.anno.Gjh)")public void pointcut(){}//1.前置通知:在目標(biāo)方法執(zhí)行之前執(zhí)行@Before("pointcut()")public void before(JoinPoint joinPoint){//連接點(diǎn):獲取方法中的數(shù)據(jù)//獲取目標(biāo)對象的類型Class<?> targetClass = joinPoint.getTarget().getClass();//獲取方法名稱String methodName = joinPoint.getSignature().getName();//獲取類名String className = joinPoint.getSignature().getDeclaringTypeName();Object[] objs = joinPoint.getArgs();System.out.println("我是前置通知");System.out.println("類型"+targetClass);System.out.println("方法名稱"+methodName);System.out.println("類名"+className);System.out.println("方法中攜帶的參數(shù)"+ Arrays.toString(objs));}//2.后置通知:在目標(biāo)方法執(zhí)行之后執(zhí)行//通過returning = "result"屬性,獲取目標(biāo)方法的返回值,當(dāng)作參數(shù)傳給result@AfterReturning(value = "pointcut()",returning = "result")public void afterReturning(Object result){System.out.println("我是后置通知");System.out.println("用戶的返回值為:"+result);}//3.異常通知:目標(biāo)方法執(zhí)行報(bào)錯(cuò)時(shí),執(zhí)行該通知@AfterThrowing(value = "pointcut()",throwing = "exception")public void afterThrow(Exception exception){System.out.println("我是異常通知");System.out.println("獲取異常信息"+exception.getMessage());exception.printStackTrace();//所有異常}//4.最終通知:目標(biāo)方法之后都要執(zhí)行的通知@After("pointcut()")public void after(){System.out.println("我是最終通知,都要執(zhí)行");}//5.(重點(diǎn))環(huán)繞通知:在目標(biāo)方法執(zhí)行前后都要執(zhí)行,控制目標(biāo)方法@Around("pointcut()")public Object around(ProceedingJoinPoint joinPoint)throws Throwable{System.out.println("環(huán)繞通知執(zhí)行前");Object result = joinPoint.proceed();System.out.println("環(huán)繞通知執(zhí)行后");return result;}}編輯AOP類2
package com.jt.aop;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component;@Component //將該類交給spring容器管理 @Aspect //標(biāo)識(shí)切面類 @Order(1) //第一個(gè)執(zhí)行 public class SpringAOP2 {//通過環(huán)繞通知 指定切入點(diǎn)表達(dá)式@Around("@annotation(com.jt.anno.Gjh)")public Object around(ProceedingJoinPoint joinPoint) throws Throwable{//1.如果有下一個(gè)通知,則執(zhí)行通知方法,沒有通知,則執(zhí)行目標(biāo)方法System.out.println("執(zhí)行環(huán)繞通知B開始");Object result = joinPoint.proceed();System.out.println("執(zhí)行環(huán)繞通知B結(jié)束");return result;}}? 8.關(guān)于代理對象生成策略說明
默認(rèn)策略:
? ? ? ? 1.Spring中默認(rèn)采用的動(dòng)態(tài)代理的規(guī)則是JDK代理。
? ? ? ? 2.如果需要修改為CGLIB代理,則添加以下代碼。(SpringBoot默認(rèn)代理模式采用CGLIB代理,如果需要修改為JDK代理,則需要修改配置文件)
@Configuration @ComponentScan("com.jt") @EnableAspectJAutoProxy(proxyTargetClass = true) //開啟AOP,啟用切面自動(dòng)注解 public class SpringConfig { }七、關(guān)于Spring總結(jié)
?1.為什么學(xué)習(xí)Spring框架
讓程序設(shè)計(jì)實(shí)現(xiàn)松耦合
?2.什么是面向接口編程
以后對象中的屬性一般寫接口,java中多態(tài)的體現(xiàn),屬性類型更加靈活? ?松耦合
3.什么是IOC
IOC為控制反轉(zhuǎn)
4.Spring容器啟動(dòng)方式
1.xml方式? ? ? ? 2.注解方式
5.什么時(shí)候使用工程模式:
? ? ? ? 1.對象不能直接實(shí)例化的時(shí)候
? ? ? ? 2.spring框架整合其他第三方框架時(shí)使用
6.單例/多例模式
? ? ? ? 1.@Scope("singleton")? ? ? 單例模式? ? ?默認(rèn)
? ? ? ? 2.@Scope("prototype")? ? 多例模式
7.懶加載規(guī)則
? ? ? ? 默認(rèn)規(guī)則下,懶加載無效,添加注解@Lazy 有效,只對單例模式有效,多例默認(rèn)是懶加載
8.Spring生命周期管理
4個(gè)過程: 1.對象創(chuàng)建? 2.對象初始化@PostConstruct? ?init() 3.業(yè)務(wù)調(diào)用 4.對象銷毀@PreDestroy? ? ? destroy()
9.Spring中依賴注入的注解@Autowired
? ? ? ? 1.默認(rèn)按照類型注入
? ? ? ? 2.可以按照名稱注入? ?再叫ai@Qualifier("cat")
? ? ? ? 3.@Resource注解
10.MVC設(shè)計(jì)思想
? ? ? ? View視圖層? ? ? ? Model業(yè)務(wù)層? ? ? ? Control控制層
????????根據(jù)MVC設(shè)計(jì)思想:層級(jí)代碼結(jié)構(gòu)Controller/Service/Mapper|Dao
11.@Value
? Spring為屬性動(dòng)態(tài)復(fù)制 基本類型和String和集合(幾乎不用)
12.動(dòng)態(tài)代理
? ? ? ? ·JDK動(dòng)態(tài)代理/CGLIB動(dòng)態(tài)代理
13.AOP 面向切面編程??
? ? ? ? 1.在不改變源碼的條件下對方法進(jìn)行擴(kuò)展
? ? ? ? 2.@Aspect? ? ? ? 標(biāo)識(shí)切面
? ? ? ? 3.@Pointcut? ? ? ? 標(biāo)識(shí)切入點(diǎn)表達(dá)式? 4種寫法 2種常用
? ? ? ? 4.五個(gè)通知注解:@Before()? @AfterReturning? ?@AfterThrowing? ?@After? ?@Around
? ? ? ? 5.@EnableAspectJAutoProxy? ?????????開啟AOP
? ? ? ? 6.@Order? ?????????排序注解
14.配置pom.xml文件,以下配置將默認(rèn)激活-dev.yml配置文件
14.1pom文件
<profiles><profile><id>dev</id><activation><!--默認(rèn)激活--><activeByDefault>true</activeByDefault></activation><properties><spring.profiles.active>dev</spring.profiles.active></properties></profile><profile><id>prod</id><properties><spring.profiles.active>prod</spring.profiles.active></properties></profile></profiles>
?
14.2yml文件中寫入:spring: profiles: active: dev
14.3. 項(xiàng)目啟動(dòng)的時(shí)候也可以設(shè)置 Java -jar xxxxxx.jar spring.profiles.actiove=prod 也可以這樣啟動(dòng)設(shè)置配置文件,但是這只是用于開發(fā)和測試。
14.4. 配置文件數(shù)據(jù)的讀取:
比如我在文件中配置了一個(gè)?
massage:data:name: qibaoyi
我在類中想要獲取他 需要這樣去寫: @Value("${message.data.name}")
private String name;后面你取到變量name 的值就是配置文件中配置的值。
總結(jié)
以上是生活随笔為你收集整理的SSM三大框架Spring的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql防注入方法_防止SQL注入的六
- 下一篇: Linux stmac网卡代码分析---