javascript
Spring(三)——HelloSpring、IOC创建对象的方式、属性注入、自动装配、使用注解开发
文章目錄
- 1. 簡介
- 2. IOC理論推導
- 3. HelloSpring
- 4. IOC創(chuàng)建對象的方式
- 4.1 使用無參構(gòu)造創(chuàng)建對象(默認)
- 4.2 使用有參構(gòu)造創(chuàng)建對象
- 5. Spring配置
- 5.1 別名
- 5.2 bean的配置
- 5.3 import標簽
- 6. 屬性注入
- 7. 自動裝配
- 7.1 測試環(huán)境搭建
- 7.2 byName自動裝配
- 7.3 byType自動裝配
- 7.4 使用注解實現(xiàn)自動裝配
- 8. 使用注解開發(fā)
1. 簡介
Spring就是一個輕量級的控制反轉(zhuǎn)(IOC) 和面向切面編程(AOP)的框架!
Spring目的:解決企業(yè)應(yīng)用開發(fā)的復雜性
2. IOC理論推導
傳統(tǒng)new對象的邏輯開發(fā):
dao—>daoImpl—>service—>serviceImpl
如果用戶想要切換數(shù)據(jù)庫實現(xiàn),所有的主動權(quán)在程序員的手上,需要修改程序。
所以要控制反轉(zhuǎn):原來程序員的主動權(quán)要交給用戶;需要對外暴露接口(set方法)
控制反轉(zhuǎn)IoC(Inversion of Control),是一種設(shè)計思想,DI(依賴注入)是實現(xiàn)IoC的一種方法
(1)在pom.xml 中導入junit 測試依賴
<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>(2)在dao層創(chuàng)建接口,以及接口的實現(xiàn)類
- UserMapper接口
- 接口的實現(xiàn)類UserMapperImpl
- 接口的實現(xiàn)類UserMapperMysqlImpl
(3)同樣在service層(調(diào)用dao層)創(chuàng)建接口,以及接口的實現(xiàn)類
- UserService接口
- 接口的實現(xiàn)類UserServiceImpl
(4)在test層,創(chuàng)建測試類
用戶根據(jù)不同的需求進行修改測試類代碼
- 調(diào)用UserMapperImpl實現(xiàn)類的方法
注釋掉UserMapperMysqlImpl userMapper = new UserMapperMysqlImpl();這行代碼即可
測試結(jié)果:
- 調(diào)用UserMapperMysqlImpl實現(xiàn)類的方法
注釋掉UserMapperImpl userMapper = new UserMapperImpl();這行代碼即可
測試結(jié)果:
3. HelloSpring
項目目錄:
(1)在pom.xml 中導入spring-webmvc依賴
(2)創(chuàng)建實體類 Hello
package com.zz.pojo;public class Hello {private String name;public void setName(String name) {this.name = name;}public void show(){System.out.println("Hello,"+name);} }注意:set方法必須要有
(3)在resources目錄下創(chuàng)建配置文件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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!--注冊到Spring Bean就是我們的對象Hello hello = new Hello();hello.setName();id=對象name=屬性value=屬性值 --> <bean id="hello" class="com.zz.pojo.Hello"><property name="name" value="Spring"/></bean> </beans>(4)編寫測試類測試
@Testpublic void test2(){ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");Hello hello = (Hello) context.getBean("hello");hello.show(); }運行結(jié)果:
- hello 對象是由Spring創(chuàng)建的
- hello 對象的屬性是由Spring容器設(shè)置的
4. IOC創(chuàng)建對象的方式
4.1 使用無參構(gòu)造創(chuàng)建對象(默認)
實體類中需要set方法,配置文件中通過property標簽注入
(1)實體類
package com.zz.pojo;public class User {private String name;public User() {System.out.println("對象被創(chuàng)建了");}public void setName(String name) {this.name = name;}public void show(){System.out.println("name="+name);} }(2)配置文件
<bean id="user" class="com.zz.pojo.User"><property name="name" value="大佬"/> </bean>(3)測試類
@Testpublic void test3(){//在加載容器時,所有bean就已經(jīng)被創(chuàng)建了ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User) context.getBean("user");user.show();}測試結(jié)果:
注意:在加載容器時,所有bean就已經(jīng)被創(chuàng)建了
4.2 使用有參構(gòu)造創(chuàng)建對象
實體類中需要有參構(gòu)造方法,配置文件中通過constructor-arg標簽注入
(1)實體類
package com.zz.pojo;public class User {private String name;public User(String name) {this.name = name;}public void show(){System.out.println("name="+name);} }(2)配置文件
<bean id="user" class="com.zz.pojo.User"><!--有參構(gòu)造注入--><constructor-arg name="name" value="大佬2"/> </bean>(3)測試類
與上面無參測試類相同
測試結(jié)果:
5. Spring配置
5.1 別名
<!--別名,如果添加了別名,我們也可以使用別名獲取到這個對象--> <alias name="user" alias="userNew"/>5.2 bean的配置
id : bean 的唯一標識符,也就是相當于我們學的對象名
class : bean 對象所對應(yīng)的全限定名 : 包名 + 類型
name :也是別名,而且name 可以同時取多個別名
5.3 import標簽
import一般用于團隊開發(fā)使用,他可以將多個配置文件,導入合并為一個。
在applicationContext.xml文件中有如下代碼,而沒有Bean的配置
<import resource="spring-dao.xml"/>Bean的配置寫在spring-dao.xml文件中
<bean id="user" class="com.zz.pojo.User"><constructor-arg name="name" value="大佬2"/> </bean>依然可以獲取user對象,測試成功。
6. 屬性注入
(1)創(chuàng)建實體類 Address 和Student
package com.zz.pojo;public class Address {private String address;public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "Address{" +"address='" + address + '\'' +'}';} } package com.zz.pojo;import java.util.*;public class Student {private String name;private Address address;private String[] books;private List<String> list;private Map<String,String> map;private Set<String> set;private String wife; //nullprivate Properties info;public void setName(String name) {this.name = name;}public void setAddress(Address address) {this.address = address;}public void setBooks(String[] books) {this.books = books;}public void setList(List<String> list) {this.list = list;}public void setMap(Map<String, String> map) {this.map = map;}public void setSet(Set<String> set) {this.set = set;}public void setWife(String wife) {this.wife = wife;}public void setInfo(Properties info) {this.info = info;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", address=" + address +", books=" + Arrays.toString(books) +", list=" + list +", map=" + map +", set=" + set +", wife='" + wife + '\'' +", info=" + info +'}';} }(2)配置文件student.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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="addr" class="com.zz.pojo.Address"><property name="address" value="安徽"/></bean><bean id="student" class="com.zz.pojo.Student"><!--常量注入--><property name="name" value="大佬"/><!--引用類型 是對象用ref--><property name="address" ref="addr"/><!--數(shù)組類型--><property name="books"><array><value>語文</value><value>數(shù)學</value><value>英語</value></array></property><!--list類型--><property name="list"><list><value>list1</value><value>list2</value></list></property><!--map類型--><property name="map"><map><entry key="k1" value="v1"/><entry key="k2" value="v2"/></map></property><!--set類型--><property name="set"><set><value>set1</value><value>set2</value></set></property><!--null注入--><property name="wife"><null/></property><!--properties類型--><property name="info"><props><prop key="id">001</prop><prop key="name">zz</prop></props></property></bean></beans>(3)測試類 MyTest
@Testpublic void test4(){ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");Student student = (Student) context.getBean("student");System.out.println(student.toString());}測試結(jié)果:
bean的作用域:scope屬性
singleton:單例,容器中只存心一個對象(默認)
prototype:非單例,每次創(chuàng)建新對象
其余的 request、session、application這些只能在web開發(fā)中使用到。
7. 自動裝配
手動裝配:一個個賦值
自動裝配:自動化賦值,不需要一個個賦值
7.1 測試環(huán)境搭建
一個人有兩個寵物
(1)在java目錄下,創(chuàng)建entity包,包下創(chuàng)建三個實體類User、Cat、Dog
7.2 byName自動裝配
autowire="byName"會自動在容器上下文中查找,和自己對象set方法后面的值對應(yīng)的 bean id
所以下列代碼中,手動配置的那兩行可以注釋掉
user.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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!--cat和dog都是引用類型,且沒有屬性--><bean id="cat" class="com.zz.entity.Cat"/><bean id="dog" class="com.zz.entity.Dog"/><!--自動配置--><bean id="user" class="com.zz.entity.User" autowire="byName"><property name="name" value="大佬"/><!--<property name="cat" ref="cat"/>--><!--<property name="dog" ref="dog"/>--></bean></beans>MyTest測試類:
@Testpublic void test5(){ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User) context.getBean("user");System.out.println(user);user.getCat().shout();user.getDog().shout(); }測試結(jié)果:
7.3 byType自動裝配
autowire="byType"會自動在容器上下文中查找,和自己對象屬性類型相同的bean
只將上述代碼中autowire="byName"改為autowire=“byType”,其余代碼均與上面相同,測試結(jié)果也相同
但是如果這個類型有多個bean,就會報錯
小結(jié):
- byname的時候,需要保證所有bean的id唯一,并且這個bean需要和自動注入的屬性的set方法的值一致!
- bytype的時候,需要保證所有bean的class唯一,并且這個bean需要和自動注入的屬性的類型一致!
- 在真實的開發(fā)中,我們不這么用,而是使用注解實現(xiàn)自動配置
7.4 使用注解實現(xiàn)自動裝配
要使用注解須知:
在applicationContext.xml中
-
導入約束 : context約束
xmlns:context=“http://www.springframework.org/schema/context”
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd"> -
配置注解的支持 : context:annotation-config/
添加后,完整的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"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><context:annotation-config/><import resource="user.xml"/></beans>(1)@Autowired注解
- 直接在屬性上使用即可!也可以在set方式上使用!
- 使用Autowired 我們可以不用編寫Set方法了,前提是你這個自動裝配的屬性在 IOC(Spring)容器中存在,且符合名字byname!
User類中刪除了setCat和setDog方法,添加了@Autowired注解:
package com.zz.entity;import org.springframework.beans.factory.annotation.Autowired;public class User {private String name;@Autowired //自動裝配private Cat cat;@Autowiredprivate Dog dog;public void setName(String name) {this.name = name;}public String getName() {return name;}public Cat getCat() {return cat;}public Dog getDog() {return dog;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", cat=" + cat +", dog=" + dog +'}';} }user.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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!--cat和dog都是引用類型,且沒有屬性--><bean id="cat" class="com.zz.entity.Cat"/><bean id="dog" class="com.zz.entity.Dog"/><!--自動配置--><bean id="user" class="com.zz.entity.User"><property name="name" value="大佬"/></bean> </beans>測試類不變,依然能測出相同的結(jié)果
科普:@Nullable 字段標記了這個注解,說明這個字段可以為null;
(2)@Resource注解
public class People {@Resource(name = "cat2")private Cat cat;@Resourceprivate Dog dog;}小結(jié):
@Resource 和@ Autowired 的區(qū)別:
- 都是用來自動裝配的,都可以放在屬性字段上
- @ Autowired 通過byType的方式實現(xiàn),而且必須要求這個對象存在! 【常用】
- @ Resource 默認通過byname的方式實現(xiàn),如果找不到名字,則通過byType實現(xiàn)!如果兩個都找不到的情況下,就報錯! 【常用】
- 執(zhí)行順序不同:@ Autowired 通過byType的方式實現(xiàn)。@ Resource 默認通過byname的方式實現(xiàn)
8. 使用注解開發(fā)
(1)在Spring4之后,要使用注解開發(fā),必須要保證 aop的包導入了
(2)使用注解需要導入context約束,增加注解的支持!
applicationContext.xml文件:
不用再編寫people.xml 文件,不用進行bean標簽之類的配置
(3)實體類People:
@Component(“people”) 相當于 : < bean id=“people” …/>
@Value("大哥”)相當于: < property name=“name” value=“大哥”/>
@Scope(“prototype”) 表示作用域,也分為原型模式prototype和單例模式singleton
(4)測試類:
@Testpublic void test6(){ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");People people = (People) context.getBean("people");System.out.println(people.name);}測試結(jié)果:
衍生的注解:
@Component 有幾個衍生注解,我們在web開發(fā)中,會按照mvc三層架構(gòu)分層!
-
dao 【@Repository】
-
service 【@Service】
-
controller 【@Controller】
這四個注解功能都是一樣的,都是代表將某個類注冊到Spring中,裝配Bean
小結(jié):
xml 與 注解:
- xml 更加萬能,適用于任何場合!維護簡單方便
- 注解 不是自己類使用不了,維護相對復雜!
xml 與 注解最佳實踐:
- xml 用來管理bean;
如: < bean id=“student” class=“com.zz.pojo.Student”/> - 注解只負責完成屬性的注入;
如:@Value(“小明”)
private String name; - 我們在使用的過程中,只需要注意一個問題:必須讓注解生效,就需要開啟注解的支持
總結(jié)
以上是生活随笔為你收集整理的Spring(三)——HelloSpring、IOC创建对象的方式、属性注入、自动装配、使用注解开发的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MyBatis(三)——动态SQL
- 下一篇: Spring(四)——AOP、Sprin