3、IOC創建對象的方法 使用無參構造創建對象,預設! 使用有參構造創建對象 下標賦值 <!--第一種 下標賦值--> <bean id="user" class="com.jan.pojo.User"> <constructor-arg index="0" value="鐘健"/> </bean> ...
目錄
- 3、IOC創建對象的方法
- 4、Spring配置
- 4.1、別名
- 4.2、Bean的配置
- 4.3、import
- 5、依賴註入
- 5.1、構造器註入
- 5.2、Set方式註入【重點】
- 5.3、擴展方式註入
- 5.4、bean的作用域
- 6、Bean的自動配置
- 6.1、測試
- 6.2、ByName自動裝配
- 6.3、ByType自動裝配
- 6.4、使用註解實現自動裝配
- 7、使用註解開發
- 8、使用Java的方式配置Spring
3、IOC創建對象的方法
-
使用無參構造創建對象,預設!
-
使用有參構造創建對象
- 下標賦值
<!--第一種 下標賦值--> <bean id="user" class="com.jan.pojo.User"> <constructor-arg index="0" value="鐘健"/> </bean>
-
類型創建
<!--第二種 通過類型創建 不建議使用--> <bean id="user" class="com.jan.pojo.User"> <constructor-arg type="java.lang.String" value="zhongjian"/> </bean>
-
參數名
<!-- 第三種 直接通過參數名來設置--> <bean id="user" class="com.jan.pojo.User"> <constructor-arg name="name" value="Jan"/> </bean>
總結:在配置文件載入的時候,容器中的管理的對象就已經初始化了!
4、Spring配置
4.1、別名
<!--別名,如果添加了別名,我們也可以使用別名取到這個對象-->
<alias name="user" alias="userNew"/>
4.2、Bean的配置
<!--
id: bean 的唯一標識符,也就是相當於我們學的對象名
class: bean 對象所對應的全限定名: 包名 + 類型
name: 也是別名, 而且name 可以同時取多個別名
-->
<bean id="userT" class="com.jan.pojo.UserT" name="user2 u2,u3;u4">
<property name="name" value="鐘健學習"/>
</bean>
4.3、import
-
這個import一般用於團隊開發使用,他可以將多個配置文件導入合併為一個,假設,現在項目有對人開發,將三人不同的開類需註冊到不同的bean中,我們可以利用import將所有人的beans.xml合併為一個總的!
-
張三
-
李四
-
王五
-
applicationContext
<import resource="beans.xml"/> <import resource="beans2.xml"/> <import resource="beans3.xml"/>
5、依賴註入
5.1、構造器註入
- 依賴註入:
- 依賴:bean對象的創建依賴於容器!
- 註入: bean對象中的所有屬性,由容器註入!
【環境搭建】
-
複雜類型
public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
-
真實測試對象
public class Student { private String name; private Address address; private String[] books; private List<String>hobbys; private Map<String,String> card; private Set<String> games; private String wife; private Properties info; }
-
beans.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="student" class="com.jan.pojo.Student"> <!--第一種,普通註入,value--> <property name="name" value="鐘健"/> </bean> </beans>
-
測試類
public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Student student = (Student) context.getBean("student"); System.out.println(student.getName()); } }
-
完善註入信息
<?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="address" class="com.jan.pojo.Address"> <property name="address" value="北京"/> </bean> <bean id="student" class="com.jan.pojo.Student"> <!--第一種,普通註入,value--> <property name="name" value="鐘健"/> <!--第二種,bean註入,ref--> <property name="address" ref="address"/> <!--數組註入--> <property name="books"> <array> <value>紅樓夢</value> <value>水滸傳</value> <value>三國演義</value> <value>西游記</value> </array> </property> <!--List--> <property name="hobbys"> <list> <value>聽歌</value> <value>敲代碼</value> <value>看電影</value> </list> </property> <!--Map--> <property name="card"> <map> <entry key="身份證" value="111111222222223333"/> <entry key="銀行卡" value="123456789"/> </map> </property> <!--Set--> <property name="games"> <set> <value>LOL</value> <value>COS</value> </set> </property> <!--null--> <property name="wife"> <null/> </property> <!--Properties--> <property name="info"> <props> <prop key="driver">20230102</prop> <prop key="url">男</prop> <prop key="username">root</prop> <prop key="password">123456</prop> </props> </property> </bean> </beans>
5.2、Set方式註入【重點】
5.3、擴展方式註入
我們可以使用P命名空間和C 命名空間進行註入
-
官方解釋
-
使用
<?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"> <!-- P命名空間註入,可以直接註入屬性的值 property--> <bean id="user" class="com.jan.pojo.User" p:name="鐘健" p:age="18"/> <!-- c命名空間註入,通過構造器註入 construct-args--> <!--在User類中要有無參和有參構造器才可以使用 C 命名註入--> <bean id="user2" class="com.jan.pojo.User" c:age="18" c:name="Jan"/> </beans>
-
測試
@Test public void test2(){ ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml"); //User user = context.getBean("user", User.class); User user = context.getBean("user2", User.class); System.out.println(user); }
註意點: P 命名和 C 命名空間不能直接使用,需要導入xml約束!
- P命名註入
xmlns:p="http://www.springframework.org/schema/p"
- C命名註入
xmlns:c="http://www.springframework.org/schema/c"
5.4、bean的作用域
-
單例模式(Spring預設機制)--->30分鐘的教學記得看
- 有時候併發情況下會產生延遲或數據不一致,單線程一般用這個
<bean id="user2" class="com.jan.pojo.User" c:age="18" c:name="Jan" scope="singleton"/>
-
原型模式:每次從容器中get的時候,都會產生一個新對象!
<bean id="user2" class="com.jan.pojo.User" c:age="18" c:name="Jan" scope="prototype"/>
- 別特浪費資源,多線程可以使用原型模式
-
其餘的request、session、application,這些個只能在web開發中使用的!
6、Bean的自動配置
- 自動配置是Spring滿足bean依賴的一種方式
- Spring會在上下文中自動尋找,並自動給bean裝配屬性!
在spring的三種配置方式:
- 在xml中顯示的配置
- 在java中顯示的配置
- 隱式 的自動裝配bean【重要】
6.1、測試
環境搭建:一個人有兩個寵物!
- 原來的xml配置
<bean id="cat" class="com.jan.pojo.Cat"/>
<bean id="dog" class="com.jan.pojo.Dog"/>
<bean id="people" class="com.jan.pojo.People">
<property name="name" value="鐘健"/>
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
</bean>
6.2、ByName自動裝配
<bean id="cat" class="com.jan.pojo.Cat"/>
<bean id="dog" class="com.jan.pojo.Dog"/>
<!--
ByName: 會自動在容器上下文中查找,和自己對象set方法後面的值對應的 bean id!
ByType: 會自動在容器上下文中查找,和自己對象屬性類型相同的 bean !
-->
<bean id="people" class="com.jan.pojo.People" autowire="byName">
<property name="name" value="鐘健"/>
</bean>
6.3、ByType自動裝配
<bean class="com.jan.pojo.Cat"/>
<bean class="com.jan.pojo.Dog"/>
<!--
ByName: 會自動在容器上下文中查找,和自己對象set方法後面的值對應的 bean id!
ByType: 會自動在容器上下文中查找,和自己對象屬性類型相同的 bean !
-->
<bean id="people" class="com.jan.pojo.People" autowire="byType">
<property name="name" value="鐘健"/>
</bean>
小結:
- byname的時候,需要保證所有的bean的id唯一,並且這個bean需要和自動註入的屬性的set方法的值一致!
- bytype的時候,需要保證所有的bean的class唯一,並且這個bean需要和自動註入的屬性的類型一致!
6.4、使用註解實現自動裝配
jdk1.5支持的註解,Spring2.5就支持註解了!
The introduction of annotation-based configuration raised the question of whether this approach is “better” than XML.
要使用註解須知:
- 導入約束。context約束
- 配置註解支持: 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!
科普:
@Nullable 欄位標記了這個註解,說明瞭這個欄位可以為null;
public People(@Nullable String name) {
this.name = name;
}
public @interface Autowired {
boolean required() default true;
}
測試代碼
public class People {
//如果顯示定義了Aurowired的required的屬性為false,說明這個對象可以為null,否則不允許為空!
@Autowired(required = false)
private Cat cat;
@Autowired
private Dog dog;
private String name;
}
如果 @Autowired 自動裝配的環境比較複雜,自動裝配無法通過一個註解【@Autowired】完成的時候,我們可以誰用@Qualifier(value == "xxx")去配置@Autowired的使用,指定一個唯一的bean對象註入!
public class People {
@Autowired
@Qualifier(value = "cat222")
private Cat cat;
@Autowired
@Qualifier(value = "dog222")
private Dog dog;
private String name;
}
xml的代碼
<bean id="cat222" class="com.jan.pojo.Cat"/>
<bean id="cat111" class="com.jan.pojo.Cat"/>
<bean id="dog222" class="com.jan.pojo.Dog"/>
<bean id="dog111" class="com.jan.pojo.Dog"/>
<bean id="people" class="com.jan.pojo.People" />
@Resource註解
public class People {
@Resource(name = "cat2")
private Cat cat;
@Resource
private Dog dog;
}
小結:
@Autowired和@Resource的區別:
- 都是用來自動裝配的,都可以放在屬性欄位上
- @Autowired 通過 byType 的方式實現,而且必須要求這個對象存在!【常用】
- @Resource 預設通過 byName的方式實現的,如果找不到名字,則通過byType實現!(名字 屬性)如果兩個都找不到的情況下,就報錯!【常用】
- 執行順序不同: @Autowired 通過 byType 的方式實現。@Resource 通過 byName的方式實現的。
7、使用註解開發
在Spring4之後,要使用註解開發,必須要保證aop包的註入!
使用註解需要導入context約束,增加註解的支持!
<?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>
-
bean
-
屬性如何註入
//等價於 <bean id="user" class="com.jan.pojo.User"/> //@Component 組件 @Component public class User { public String name ; //相當於 <property name="name" value="zhongjian"/> @Value("zhongjian") public void setName(String name) { this.name = name; } }
-
衍生的註解
@Component有幾個衍生註解,我們在web開發中,會按照mvc三層架構分層!
-
dao 【@Repository】
-
service 【@Service】
-
controller 【@Controller】
這四個註解功能都是一樣的,都是代表將某個類註冊到Spring中,裝配Bean。
-
-
自動裝配置
- @Autowired:自動裝配,通過屬性,名字 如果Autowired不能唯一自動裝配上屬性,則需要通過@Qualifier(value == "xxx") - @Nullable 欄位標記了這個註解,說明瞭這個欄位可以為null; - @Resource:自動裝配,通過名字,屬性
-
作用域
@Scope("prototype") @Scope("singleton")
@Component @Scope("prototype") public class User { public String name ; //相當於 <property name="name" value="zhongjian"/> @Value("zhongjian") public void setName(String name) { this.name = name; } }
-
小結
xml與註解:
- xml:更加萬能,適用於任何場合!維護簡單方便
- 註解:不是註解類使用不了,維護相對複雜
xml與註解最佳實踐:
-
xml用來管理bean;
-
註解只負責完成屬性的註入;、
-
我們在使用的過程中,只需要註意一個問題:必須讓註解生效,就需要開啟註解的支持
<!-- 指定要掃描的包,這個包下的註解就會生效 --> <context:component-scan base-package="com.jan.pojo"/> <context:annotation-config/>
8、使用Java的方式配置Spring
我們現在要完全不適用Spring 的 xml 配置了,全權交給Java來做!
JavaConfig 是 Spring 的一個字項目,在 Spring 4之後, 它成為了一個核心功能!
實體類
package com.jan.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//這個註解的意思,就是說明這個類被Spring接管了,註冊到了容器中
@Component
public class User {
private String name;
public String getName() {
return name;
}
@Value("ZHONGJIAN") //屬性註入值
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
配置文件
package com.jan.config;
import com.jan.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
//這個也是Spring容器托管,註冊到容器中,因為它本來就是一個@Component
//@Configuration代表這是一個配置類,就和 我們之前看到的beans.xml
@Configuration
@ComponentScan("com.jan.pojo")
@Import(JanConfig2.class)
public class JanConfig {
//註冊一個Bean,就相當於我們之前寫的一個bean標簽
//這個方法的名字(eg:user),就相當於bean標簽中的id屬性
//這個方法的返回值(eg:User),就相當於bean標簽中的class屬性
@Bean
public User user(){
return new User(); // 就是返回要註入到bean的對象!
}
}
測試類
public class MyTest {
public static void main(String[] args) {
//如果完全使用了配置類的方式去做,我們就只能通過 AnnotationConfig 上下文來獲取容器,通過配置類的class對象載入!
ApplicationContext context = new AnnotationConfigApplicationContext(JanConfig.class);
User getUser = context.getBean("user", User.class);
System.out.println(getUser.getName());
}
}
這種純Java的配置方式,在SpringBoot中隨處可見!