直播獲獎
Spring
1.0 理念
-
官方
[Spring]: https://spring.io/
[Spring 官方下載地址]: https://repo.spring.io/libs-release-local/org/springframework/spring/
[maven store]: https://mvnrepository.com/ -
理念 使現有的技術更加容易使用
-
maven依賴
-
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.5.RELEASE</version> </dependency>
1.1 優點
- Spring是一個開源免費的框架!
- Spring'是一個輕量級非入侵框架
- 控制反轉(IOC)面向切面程式設計(AOP)
- 支援事務的處理,對框架整合的支援
Spring就是一個輕量級控制反轉和麵向切面程式設計的框架
1.2 模組
1.3 弊端
- 發展時間太久了,違背了原來的理念,配置十分的繁瑣,俗稱配置煉獄
1.4 IOC理論
-
這種思想,從本質上解決了問題,我們程式設計師不用再去管理物件的建立,系統的耦合性大大降低了,可以更加專注在業務的實現上,將控制權交給使用者
-
在業務中,使用者的需求可能會影響我們的程式碼,我們需要根據客戶的需求去修改原始碼,如果程式程式碼非常龐大,修改一次非常的昂貴
-
我們使用一個Set介面實現,將控制權交給使用者 被動的接受物件
-
private UserDao userDao; //利用set進行注入 public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void getUser() { userDao.getUser(); }
-
系統的的耦合性大大的降低了
1.5 IOC本質
* IOC實質是一種理論,DI(依賴注入)是實現IOC的一種方法 * IOC是Spring的核心內容,使用多種方式來實現IOC,可以使用XML配置,也可以使用註解,新版的spring也可以零配置實現 * Spring 在初始化的時候先讀取配置檔案,根據配置檔案建立組織物件進入容器中,使用時在將物件取出
1.6 Hello Spring
- 編寫 hello class
public class Hello {
private String name;
public Hello() {
}
public Hello(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- 編寫spring 配置檔案
<?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">
<!--使用spring建立物件 在spring中這些都成為bean -->
<bean id="hello" class="com.immortal.pojo.Hello">
<property name="name" value="immortal" ></property>
</bean>
</beans>
- 測試
public static void main(String[] args) {
//獲取spring的上下文物件
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//get bean
Hello hello = context.getBean("hello", Hello.class);
System.out.println(hello);
}
1.7 IOC建立物件的方式
-
使用無參構造器賦值 預設
-
使用構造器賦值
-
下標賦值
-
<bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg index="0" value="7500000"/> <constructor-arg index="1" value="42"/> </bean>
-
型別
-
<bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg type="int" value="7500000"/> <constructor-arg type="java.lang.String" value="42"/> </bean>
-
通過引數名進行賦值
-
<beans> <bean id="beanOne" class="x.y.ThingOne"> <constructor-arg ref="beanTwo"/> <constructor-arg ref="beanThree"/> </bean> <bean id="beanTwo" class="x.y.ThingTwo"/> <bean id="beanThree" class="x.y.ThingThree"/> </beans>
-
-
spring在載入配置檔案的時候,會把容器中所有的物件進行初始化
1.8 別名 alias
-
alias標籤
-
<?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"> <!--使用spring建立物件 在spring中這些都成為bean --> <bean id="hello" class="com.immortal.pojo.Hello"> <property name="name" value="immortal" ></property> </bean> <!--別名 alias hello 和 aliasHello 都可以使用 --> <alias name="hello" alias="aliasHello"></alias> </beans>
-
bean name屬性 別名
-
<?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"> <!--使用spring建立物件 在spring中這些都成為bean 我們一般使用name屬性去起別名 ,可是設定多個 用逗號隔開 --> <bean id="hello" class="com.immortal.pojo.Hello" name="aliasHello"> <property name="name" value="immortal" ></property> </bean> </beans>
1.9 Import
-
匯入其他的spring 配置檔案
-
<?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"> <!--匯入beans配置檔案--> <import resource="beans.xml"></import> </beans>
2.0 DI 依賴注入
-
構造器注入 上面有
-
環境搭建
-
Student
-
public class Student { private String name; private Address address; private String[] book; private List<String> habbys; private Map<String,String> card; private Set<String> game; private Properties info; private String wife; }
-
Address
-
public class Address { }
-
beans.xml spring配置檔案
-
-
Set 方式注入 重點
-
<?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"> <!--使用spring建立物件 在spring中這些都成為bean 我們一般使用name屬性去起別名 ,可是設定多個 用逗號隔開 --> <bean id="address" class="com.immortal.pojo.Address"> </bean> <bean id="student" class="com.immortal.pojo.Student" name="s"> <!--普通值的注入 value--> <property name="name" value="immortal"/> <!--引用值的注入 ref--> <property name="address" ref="address"/> <!--陣列的注入--> <property name="book"> <array> <value>彙編入門到入獄</value> <value>Java入門到放棄</value> <value>C語言程式設計</value> </array> </property> <!--List注入--> <property name="habbys"> <list> <value>學BUG</value> <value>寫BUG</value> <value>改BUG</value> </list> </property> <!--Map注入--> <property name="card"> <map> <entry key="身份證" value="2222222222222222222"></entry> </map> </property> <!--Set注入--> <property name="game"> <set> <value>LOL</value> <value>CS</value> <value>DNF</value> </set> </property> <!--Null注入--> <property name="wife"> <null/> </property> <!--propertys注入--> <property name="info"> <props> <prop key="driver">mysql</prop> <prop key="url">mysql</prop> <prop key="user">root</prop> <prop key="pwd">123456</prop> </props> </property> </bean> </beans>
-
-
擴充套件方式注入
-
P名稱空間 需要匯入約束 p=property
-
<?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:p="http://www.springframework.org/schema/p" <!--匯入名稱空間--> xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="user" class="com.immortal.pojo.User" p:name="immortal" p:age="10"></bean> </beans>
-
為了測試方便這裡匯入junit
-
<!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency>
-
C名稱空間 需要匯入約束 c= constructor
-
<?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:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <!--匯入名稱空間--> <bean id="user" class="com.immortal.pojo.User" p:name="immortal" p:age="10"></bean> <bean id="u" class="com.immortal.pojo.User" c:age="10" c:name="immortal"></bean> </beans>
2.1 Bean的作用域
-
單例模式
-
<bean id="user" class="com.immortal.pojo.User" scope="singleton"></bean>
-
原型模式 多個物件
-
<bean id="user" class="com.immortal.pojo.User" scope="prototype"></bean>
-
其餘的只能在web中使用
2.2 Bean的自動裝配
-
自動裝配時Spring滿足bean依賴的一種方式
- spring在上下文z中自動尋找,Bean自動裝配,
-
在spring有三種裝配的的方式
- xml
- java顯示配置
- 隱式的自動裝配 重要
-
<?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:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="cat" class="com.immortal.pojo.Cat"></bean> <bean id="dog" class="com.immortal.pojo.Dog"></bean> <!-- byName會在上下文中尋找和自己set方法後面對應值的bean id byTypy會在上下文中尋找和自己屬性一樣的bean --> <bean id="person" class="com.immortal.pojo.Person" autowire="byName"> <property name="name" value="immortal"/> </bean> </beans>
2.3 使用註解完成自動裝配
-
要使用註解須知
-
匯入配置
-
配置註解的支援
-
<?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/> </beans>
-
-
@Autowired
- 直接在屬性在使用,也可以在set方法上使用 可以去掉Set方法
- 使用Autowired可以不用編寫set方法,因為它底層使用反射實現的
-
@Qualifier
-
指定裝配的bean值注入 一般與@Autowired一起使用
-
@Autowired @Qualifier(value = "dog") private Dog dog;
-
-
@Resource 和Autowired的區別
- 都是用於自動裝配,都可以放在屬性欄位上
- @Autowired 預設byType實現通過 找不到byName的方式實現的
- @Resource 預設通過byName的方式實現的,找不到則通過byType實現,在找不到就報錯
2.4 使用註解開發
-
使用註解開發需要開啟註解支援,掃描指定的包
-
<?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:component-scan base-package="com.immortal.pojo"/> <!--開啟註解支援 --> <context:annotation-config/> </beans>
-
@Component //元件 說明這個被類被spring託管了 用在類上 @Value // 注入值 用在屬性,set方法上
-
衍生的註解 Component,我們在web開發中,會按照mvc三層架構分層!
- dao @Repository
- service @Service
- controller @Controller
- 將類放入容器中
-
作用域的註解scope
-
@Scope
-
package com.immortal.pojo; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component @Scope(value = "singleton") public class User { @Value("immortal") private String name; @Override public String toString() { return "User{" + "name='" + name + '\'' + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
-
2.5 使用java的方式配置Spring
-
@Configuration 說明是spring的配置類
-
@ComponentScan 指定掃描的包
-
@Import 匯入其他配置類
-
@Bean 指定是一個bean
-
@Configuration @ComponentScan("com.immortal") @Import(LogConfig.class) public class ImmortalConfig { //註冊一個bean,相當於一個bean標籤 //這個方法的名字,就是標籤的id屬性 //這個方法的返回值,就相當於class屬性 @Bean public User user(){ return new User(); //這裡返回的就是要注入的物件 } }
-
測試的話要用這個類 註解的
-
@Test public void Test(){ ApplicationContext context = new AnnotationConfigApplicationContext(ImmortalConfig.class); User user = (User) context.getBean("user"); System.out.println(user.toString()); }
2.6 代理模式
-
代理模式的好處
- 可以使真實角色的操作更加純粹,不用去關注一些公共的業務
- 公共業務交給代理角色,實現了業務的分工
- 公共業務發生擴充套件,方便集中管理
-
缺點
- 一個真實角色就會產生一個代理角色,程式碼量會翻倍,開發效率降低
-
靜態代理
-
介面
-
//租房介面 public interface Rent { public void rent(); }
-
真實角色
-
//房東 public class House implements Rent{ public void rent() { System.out.println("房東出租房子..."); } }
-
代理角色
-
//中介 public class Client implements Rent{ private House house; public Client(House house) { this.house = house; } public void rent() { seeHouse(); house.rent(); contract(); } public void seeHouse(){ System.out.println("中介帶看房啊..."); } public void contract(){ System.out.println("中介籤合同..."); } }
-
客戶
-
//客戶 public class Proxy { public static void main(String[] args) { Client client = new Client(new House()); client.rent(); } }
-
-
縱向開發 橫切進去
-
動態代理
-
動態代理和靜態代理角色一樣
-
動態代理使動態生成的,不是我們直接寫的
-
動態代理分為兩大類:基於介面的動態代理,基於類的動態代理
- 基於介面----jdk 動態代理
- 基於類: cglib
- java位元組碼 java ssist
-
需要了解2個類
-
proxy 代理 invocationHandler 呼叫處理程式
-
解決了靜態代理的問題
-
public class HouseInvocationHandler implements InvocationHandler { private Object target; public void setTarget(Object target) { this.target = target; } public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { method.invoke(target, args); System.out.println(method.getName()); return null; } }
-
2.7 AOP 什麼是AOP?
(Aspect Oriented programming) 面向切面程式設計,通過預編譯的方式和執行期間動態代理實現程式功能的統一維護的一種技術
,AOP是OOP的延續,是軟體開發的的一個熱點,在Spring中是一個重要內容
2.8 AOP在spring中的作用
提供宣告式事務,允許使用者自定義切面
要使用AOP功能,需要先導包
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
-
Spring 實現AOP 日誌功能
-
方式一
-
使用spring的API 介面 實現spring介面 MethodBeforeAdvice
-
package com.immortal.log; import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; public class Log implements MethodBeforeAdvice { public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println(o.getClass().getName()+"的"+method.getName()+"被執行了"); } }
-
實現類
-
package com.immortal.service; public class UserServiceImpl implements UserService { public void add() { System.out.println("add a user"); } public void updata() { System.out.println("updata a user"); } public void delete() { System.out.println("delete a user"); } public void query() { System.out.println("query a user"); } }
-
spring 配置檔案
-
<?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" xmlns:aop="http://www.springframework.org/schema/aop" 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 http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userService" class="com.immortal.service.UserServiceImpl"></bean> <bean id="log" class="com.immortal.log.Log"></bean> <!--配置AOP--> <aop:config> <!--execution表示式 切入點的篩選規則---> <aop:pointcut id="pointcut" expression="execution(* com.immortal.service.UserServiceImpl.*(..))"/> <!--將功能放在切入點上---> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> </aop:config> </beans>
1、execution(): 表示式主體。
2、第一個*****號:表示返回型別,*號表示所有的型別。
3、包名:表示需要攔截的包名,後面的兩個句點表示當前包和當前包的所有子包,子孫包下所有類的方法。
4、第二個**號:表示類名,*號表示所有的類。
5、**(..):最後這個星號表示方法名,*號表示所有的方法,後面括弧裡面表示方法的引數,兩個句點表示任何引數。
-
-
方式二 自定義類
-
自定義一個類
-
public class diypointcut { public void before(){ System.out.println("before();"); } public void after(){ System.out.println("after();"); } }
-
在spring配置檔案中配置
-
<?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" xmlns:aop="http://www.springframework.org/schema/aop" 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 http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="diy" class="com.immortal.diy.diypointcut"/> <!--配置AOP--> <aop:config> <!--定義切面 --> <aop:aspect ref="diy"> <!--定義切入點 --> <aop:pointcut id="pointcut" expression="execution(* com.immortal.service.UserServiceImpl.*(..))"/> <!--定義點之前執行的方法 --> <aop:before method="before" pointcut-ref="pointcut"/> <aop:after method="after" pointcut-ref="pointcut"/> </aop:aspect> </aop:config> </beans>
-
-
方式三 註解實現
-
@Aspect切入點
-
@Component @Aspect public class AnnoPointCut { @Before("execution(* com.immortal.service.UserServiceImpl.*(..))") public void before(){ System.out.println(" before();"); } }
-
@Service 元件
@Service public class UserServiceImpl implements UserService { public void add() { System.out.println("add a user"); } public void updata() { System.out.println("updata a user"); } public void delete() { System.out.println("delete a user"); } public void query() { System.out.println("query a user"); } }
-
配置檔案spring
-
<?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" xmlns:aop="http://www.springframework.org/schema/aop" 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 http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <context:component-scan base-package="com.immortal"/> <context:annotation-config/> <!--開啟aop註解支援--> <aop:aspectj-autoproxy/> </beans>
-