spring學習(未完)
1、Spring
1.1、簡介
Spring框架是由於軟體開發的複雜性而建立的。Spring使用的是基本的JavaBean來完成以前只可能由EJB完成的事情。然而,Spring的用途不僅僅限於伺服器端的開發。從簡單性、可測試性和鬆耦合性角度而言,絕大部分Java應用都可以從Spring中受益。
2、IOC理論推導
3、HelloSpring
4、IOC建立物件的方式
5、Spring配置
6、依賴注入
6.1、構造器注入
6.2、Set方式注入【重點】
-
依賴注入:Set注入!
- 依賴:bean物件的建立依賴於容器
- 注入:bean物件
-
環境搭建
-
1.複雜型別Address物件
public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Address{" + "address='" + address + '\'' + '}'; } }
-
2.真實測試物件Student物件
public class Student { private String name; private Address address; private String[] books; private List<String> hobbies; private Map<String,String> card; private Set<String> games; private String wife; private Properties info; public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public String[] getBooks() { return books; } public void setBooks(String[] books) { this.books = books; } public List<String> getHobbies() { return hobbies; } public void setHobbies(List<String> hobbies) { this.hobbies = hobbies; } public Map<String, String> getCard() { return card; } public void setCard(Map<String, String> card) { this.card = card; } public Set<String> getGames() { return games; } public void setGames(Set<String> games) { this.games = games; } public String getWife() { return wife; } public void setWife(String wife) { this.wife = wife; } public Properties getInfo() { return info; } public void setInfo(Properties info) { this.info = info; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", \n address=" + address.toString() + ", \n books=" + Arrays.toString(books) + ", \n hobbies=" + hobbies + ", \n card=" + card + ", \n games=" + games + ", \n wife='" + wife + '\'' + ", \n info=" + info + '}'; } }
-
3.applicationContext.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"> <bean id="student" class="com.gong.pojo.Student"> <!-- 第一種,普通值注入,value--> <property name="name" value="龔成龍"/> </bean> </beans>
-
-
測試:
-
測試程式碼:
@Test public void setTest(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Student student = (Student) context.getBean("student"); System.out.println(student.toString()); }
-
測試結果:
-
-
完善applicationContext.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"> <bean id="address" class="com.gong.pojo.Address"> <property name="address" value="武漢"/> </bean> <bean id="student" class="com.gong.pojo.Student"> <!-- 第一種,普通值注入,value--> <property name="name" value="龔成龍"/> <!-- 第二種,Bean注入,ref--> <property name="address" ref="address"/> <!-- 第三種,陣列注入--> <property name="books"> <array> <value>Python</value> <value>Java</value> <value>C語言</value> <value>C++</value> <value>微信小程式</value> </array> </property> <!-- 第三種,list注入--> <property name="hobbies"> <list> <value>聽歌</value> <value>敲程式碼</value> <value>看火影忍者</value> </list> </property> <!-- 第四種,Map注入--> <property name="card"> <map> <entry key="身份證" value="420684202020202020"/> <entry key="銀行卡" value="3654616546515153"/> </map> </property> <!-- 第五種,Set注入--> <property name="games"> <set> <value>COC</value> <value>開心消消樂</value> <value>王者榮耀</value> <value>原神</value> </set> </property> <!-- 第六種,空值null注入--> <property name="wife"> <null/> </property> <!-- 第七種,Properties注入--> <property name="info"> <props> <prop key="driver">com.mysql.cj.jdbc.Driver</prop> <prop key="url">jdbc:mysql://127.0.0.1:3306/mybatis</prop> <prop key="username">root</prop> <prop key="password">123456</prop> </props> </property> </bean> </beans>
6.2、擴充套件方式注入
我們可以使用p名稱空間和c名稱空間進行注入
-
官方解釋:
-
環境搭建:
-
1、User物件搭建:
public class User { private String name; private int age; public User() { } public User(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
-
2、配置檔案userBeans.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:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- p名稱空間注入,可以直接注入屬性的值,是property的縮寫--> <bean id="user1" class="com.gong.pojo.User" p:age="20" p:name="龔成龍"/> <!-- c名稱空間注入,可以通過構造器注入,是constructor-arg的縮寫--> <bean id="user2" class="com.gong.pojo.User" c:age="20" c:name="龔成龍"/> </beans>
-
-
測試:
-
p名稱空間測試程式碼:
@Test public void test1(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml"); User user1 = context.getBean("user1", User.class); System.out.println(user1); }
-
控制檯輸出結果:
-
c名稱空間測試程式碼:
@Test public void test2(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml"); User user2 = context.getBean("user2", User.class); System.out.println(user2); }
-
控制檯輸出結果:
-
-
注意點:p命名和c名稱空間不能直接使用,需要匯入xml約束
xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"
6.3、bean的作用域
-
官方bean的作用域如下:
-
1.單例模式(spring預設機制):
-
使用:
<bean id="user1" class="com.gong.pojo.User" p:age="20" p:name="龔成龍" scope="singleton"/>
-
測試:
@Test public void test1(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml"); User user1 = context.getBean("user1", User.class); User user2 = context.getBean("user1", User.class); System.out.println(user1.equals(user2)); }
-
結果可以看出每次從容器get出來的物件都是同一物件:
-
-
2.原型模式(每次從容器中get物件的時候,都會獲取一個新的物件):
-
使用:
<bean id="user2" class="com.gong.pojo.User" c:age="20" c:name="龔成龍" scope="prototype"/>
-
測試:
@Test public void test2(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml"); User user1 = context.getBean("user2", User.class); User user2 = context.getBean("user2", User.class); System.out.println(user1.equals(user2)); }
-
執行結果:
-
-
其餘的request、session、application、只有在web應用中使用到!
7、bean的自動裝配
- bean的自動裝配是Spring滿足bean依賴的一種方式!
- Spring會在上下文自動尋找,並自動給bean裝配屬性!
在Spring中有三種裝配方式:
1.在xml中顯式的裝配
2.在java中顯式的裝配
3.隱式的自動裝配【重要】
7.1、測試
-
1.環境搭建
-
一個人有一個手機和一個寵物
People類
package com.gong.pojo; public class People { private String name; private Dog dog; private XiaoMi xiaoMi; public String getName() { return name; } public void setName(String name) { this.name = name; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } public XiaoMi getXiaoMi() { return xiaoMi; } public void setXiaoMi(XiaoMi xiaoMi) { this.xiaoMi = xiaoMi; } }
Dog
package com.gong.pojo; public class Dog { public void show(){ System.out.println("我是一隻可愛的小狗"); } }
XiaoMi
package com.gong.pojo; public class XiaoMi { public void show(){ System.out.println("我是一部小米手機手機"); } }
-
7.2、byName自動裝配
<?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">
<bean id="dog" class="com.gong.pojo.Dog"/>
<bean id="xiaoMi" class="com.gong.pojo.XiaoMi"/>
<!--
byName:會自動在容器上下文中尋找,和自己物件Set方法後的值一樣的bean id
-->
<bean id="people" class="com.gong.pojo.People" autowire="byName">
<property name="name" value="龔成龍"/>
</bean>
</beans>
7.3、byType自動裝配
<?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">
<bean id="dog" class="com.gong.pojo.Dog"/>
<bean id="xiaoMi" class="com.gong.pojo.XiaoMi"/>
<!--
byType:會自動在容器上下文中尋找,和自己物件屬性型別相同的bean
-->
<bean id="people" class="com.gong.pojo.People" autowire="byType">
<property name="name" value="龔成龍"/>
</bean>
</beans>
小結:
- byName的時候,需要保證所有的bean的id唯一,並且這個bean需要和自動注入的屬性的set方法的值一致!
- byType的時候,需要保證所有的bean的class唯一,並且這個bean需要和自動注入的屬性的的型別一致!
7.4使用註解實現自動裝配
1.匯入約束【context】
2.配置註解的支援context:annotation-config/
<?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方式上使用!
使用@Autowired我們可以不用編寫set方法了,前提是你這個自動裝配的屬性在IOC(Spring)容器中存在,且符合名字byName!
如果@Autowired自動裝配的環境比較複雜,自動裝配無法通過一個註解完成的時候我們可以使用@Qualifier(value=“id”)配合使用,指定一個唯一的bean物件注入!
public class People {
private String name;
@Autowired
private Dog dog;
@Autowired
@Qualifier("xiaoMi1")
private XiaoMi xiaoMi;
}
@Resource(name = "id")註解,上面的註解都是spring中的註解,這個是java自己的註解,也可以指定id去查詢對應的bean
public class People {
private String name;
@Resource(name = "dog1")
private Dog dog;
@Autowired
@Qualifier("xiaoMi1")
private XiaoMi xiaoMi;
}
小結@Resource和@Autowired的區別:
- 都是用來自動裝配的,都可以放在屬性欄位上
- @Autowired通過byType的方式實現,而且必須要求這個物件存在【常用】
- @Resource預設通過byName的方式實現,如果找不到名字,則通過byType實現!如果兩個都找不到的情況下,就會報錯!【常用】
- 執行順序不同:@Autowired通過byType的方式實現,@Resource預設通過byName的方式實現
8、使用註解開發
在spring4之後要求使用註解開發需要匯入aop的包
1.bean
@Component//相當於<bean id="user" class="com.gong.pojo.User" />
public class User {
private String name;
}
2.屬性如何注入
@Component//相當於<bean id="user" class="com.gong.pojo.User" />
public class User {
@Value("龔成龍")//相當於<property name="name" value="龔成龍"/>
private String name;
}
3.衍生的註解
@Component有幾個衍生的註解,只是在web開發中,會按照mvc三層架構分層!
-
dao【@Repository】
-
service【@Service】
-
controller【@Controller】
四個註解的功能都是一樣的,都是代表將某個類註冊到spring中,裝配Bean
4.自動裝配
@Autowired
@Resource
5.作用域
@Component//相當於<bean id="user" class="com.gong.pojo.User" />
@Scope("prototype")
public class User {
@Value("龔成龍")//相當於<property name="name" value="龔成龍"/>
private String name;
}
6.小結
xml與註解:
- xml更加萬能,適用於任何場合!維護簡單方便
- 註解不是自己類使用不了,維護相對複雜!
xml與註解最佳實踐:
-
xml用來管理bean;
-
註解只負責完成屬性的注入;
-
我們在使用的過程中,只需要注意一個問題:必須讓註解生效,就需要開解註解的支援
<!-- 指定要掃描的包,這個包下的註解就會生效--> <context:component-scan base-package="com.gong"/> <context:annotation-config/>