屬性賦值
在Java開發中屬性賦值的常規手段有兩種:
- 通過set方法注入
Student student = new Student();
student.setName("小明");
- 通過構造器注入
Worker worker = new Worker("張三", 20);
屬性注入
set方法注入
代碼部分:
Student.java
/**
* 學生類,用於演示屬性注入
* @author Katrina
*
*/
public class Student {
/*
* 一個類中若不添加構造方法,該類會有默認的無參構造方法(在頂級父類Object內)
*/
private String name;
/**
* 有參構造函數
* @param studentName 學生的姓名
*/
public Student(String studentName) {
this.name = studentName;
}
/**
* 無參構造方法 -> 默認構造方法
*/
public Student() {
System.out.println("無參構造方法被調用了");
}
public String getName() {
return name;
}
//如果註釋掉,報錯
public void setName(String name) {
this.name = name;
System.out.println("student的set方法被調用");
}
}
student-config.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">
<!-- 注入學生類 -->
<!-- 驗證路徑是否正確:按住Ctrl鼠標放上去,可跳轉 -->
<!--
相當於:Student student = new Student();
student.setName("小明");
set方法注入的注意事項:
1.需要注入的屬性必須有set方法,沒有set方法無法注入
2.需要由默認的無參構造方法,沒有則會報錯
-->
<bean class="property.Student" id="student">
<property name="name" value="小明"></property>
</bean>
</beans>
StudentTest.java
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 學生測試類,用於測試屬性注入
* @author Katrina
*
*/
public class StudentTest {
public static void main(String[] args) {
//1.獲取容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("student-config.xml");
//2.獲取類並操作
Student student = (Student) context.getBean("student");
System.out.println(student.getName());
//3.關閉容器
context.close();
}
}
效果圖:
構造器注入
1.注入方式是:通過“構造器”給實例的屬性賦值
2.使用注意事項
2.1必須要有指定構造器,否則會調用構造器失敗出現錯誤
2.2使用時,constructor-arg標籤的name屬性指向的是構造器中參數的名稱
3.使用方式
3.1constructor-arg標籤的name屬性指定值進行注入
3.2constructor-arg標籤的index屬性指定指定位置的參數注入,注意index的下標從0開始
4.注入值
4.1單值注入:
4.1.2直接量的單值:value屬性進行賦值
4.1.3引用類型的單值:ref屬性進行賦值
4.2多值注入:array、list、set、map
代碼部分:
Worker.java
import java.util.Map;
import java.util.Map.Entry;
/**
* 工人類,用於演示構造器注入
* @author Katrina
*
*/
public class Worker {
private String name;
private int age;
private Mobile mobile;
private Map<String, String> income;
//數組的屬性、list的屬性、set屬性
/**
* 含有map的構造方法
* @param income 收入
*/
public Worker(Map<String, String> income) {
this.income = income;
}
/**
* 含有引用類型的構造方法
* @param name 姓名
* @param age 年齡
* @param mobile 手機
*/
public Worker(String name, int age, Mobile mobile) {
this.name = name;
this.age = age;
this.mobile = mobile;
}
/**
* 有參構造函數
* @param name 姓名
*/
public Worker(String workerName) {
System.out.println("worker的構造方法被調用");
System.out.println("worker傳入的name是:" + workerName);
this.name = workerName;
}
/**
* 多個參數的構造函數
* @param name 姓名
* @param age 年齡
*/
public Worker(String name, int age) {
System.out.println("worker的兩個參數的構造方法被調用了");
this.name = name;
this.age = age;
}
/**
* 打印工人信息
*/
public void printInfo() {
// System.out.println("工人的姓名:" + name + ",工人的年齡是:" + age);
System.out.println("工人的姓名:" + name + ",工人的年齡是:" + age + ",手機品牌是:" + mobile.getName());
}
/**
* 打印工人的收入
*/
public void printIncome() {
for (Entry<String, String> entry : income.entrySet()) {
System.out.println("收入方式是:" + entry.getKey() + ",收入金額是:" + entry.getValue());
}
}
}
Mobile.java
/**
* 手機類
* @author Katrina
*
*/
public class Mobile {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
worker-config.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">
<!-- 注入工人類 -->
<!--
執行的代碼相當於:Worker worker = new Worker("李四");
構造器注入的注意事項:
1.要有匹配的構造器方法
2.constructor-arg的name屬性指向的是參數的名字,要與參數名字保持一致
-->
<!--
<bean class="constructor.Worker" id="worker">
構造器注入
<constructor-arg name="workerName" value="李四"></constructor-arg>
</bean>
<bean class="constructor.Worker" id="worker1">
構造器注入
<constructor-arg name="name" value="王五"></constructor-arg> 一個標籤就是給一個參數賦值
<constructor-arg name="age" value="26"></constructor-arg>
</bean>
-->
<!--
<bean class="constructor.Worker" id="worker2">
<constructor-arg index="0" value="趙柳"></constructor-arg>
<constructor-arg index="1" value="30"></constructor-arg>
</bean>
-->
<!--
<bean id="mobile" class="constructor.Mobile">
<property name="name" value="華爲"></property>
</bean>
<bean id="worker3" class="constructor.Worker">
<constructor-arg name="name" value="小明"></constructor-arg>
<constructor-arg name="age" value="20"></constructor-arg>
<constructor-arg name="mobile" ref="mobile"></constructor-arg> 關聯的類必須是已經注入到容器中的類,例如:Mobile
</bean>
-->
<!-- map構造器注入 -->
<bean id="worker4" class="constructor.Worker">
<constructor-arg name="income">
<map>
<entry key="兼職" value="1000"></entry>
<entry key="工資" value="2000"></entry>
</map>
</constructor-arg>
</bean>
</beans>
WorkerTest.java
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 工人測試類,用於演示構造器注入
* @author Katrina
*
*/
public class WorkerTest {
public static void main(String[] args) {
//1.獲取容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("worker-config.xml");
//2.獲取類並測試
// Worker worker = (Worker) context.getBean("worker");
// Worker worker1 = (Worker) context.getBean("worker1");
// worker1.printInfo();
// Worker worker2 = (Worker) context.getBean("worker2");
// worker2.printInfo();
// Worker worker3 = (Worker) context.getBean("worker3");
// worker3.printInfo();
Worker worker4 = (Worker) context.getBean("worker4");
worker4.printIncome();
//3.關閉容器
context.close();
}
}
效果圖:
part1:
注意:爲什麼前兩句話仍然會顯示在控制檯上?
解釋:只要在容器中注入實例,在Test代碼中使用ClassPathXmlApplicationContext就會被創建出來
part2:
part3:
part4:
注意:修改worker-config.xml及Worker.java實現效果圖
junit測試
1.使用步驟:
1.1引入jar包
1.2編寫測試單元:注意方法是無參數無返回值public的方法
2.常用註解
2.1@Before:在測試單元運行之前執行的
2.2@Test:測試單元,只有使用@Test標註的方法纔是測試單元
2.3@After:在測試單元完成之後運行的
引入的jar包,如圖所示:
注意:使用junit,而junit依賴hamcrest-core-1.3
bean標籤
bean標籤的常用屬性:
1.class:指向要注入實例的類的全路徑
2.id:注入的實例在容器中的表示
3.init-method(初始化方法):值爲方法的名字,在實例創建出來以後自動調用初始化的方法
4.destroy-method(銷燬方法):值爲方法的名字,在實例被銷燬的時候調用
5.lazy-init(懶加載):值爲true和false,默認爲false,實例在容器初始化的時候並不創建,在使用到的時候纔會創建
代碼部分:
Demo.java
/**
* demo類,用於演示bean的屬性
* @author Katrina
*
*/
public class Demo {
public Demo() {
System.out.println("Demo構造方法被調用了");
}
/**
* 初始化方法
*/
public void initMethod() {
System.out.println("Demo初始化方法被調用了");
}
/**
* 銷燬方法
*/
public void destroyMethod() {
System.out.println("Demo銷燬方法被調用了");
}
}
demo-config.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標籤的屬性:
destroy-method:銷燬方法,值爲類中方法的名字
init-method:初始化方法,值爲類中方法的名字
lay-init:懶加載,默認值是false,容器創建時並不創建實例,只有當調用的時候纔會創建
-->
<!-- 演示初始化方法和銷燬方法 -->
<!-- <bean id="demo" class="bean.Demo" destroy-method="destroyMethod" init-method="initMethod"></bean> -->
<!-- 演示懶加載 -->
<bean id="demo1" class="bean.Demo" lazy-init="false"></bean>
</beans>
DemoTest.java
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* demo測試類,用於演示bean的屬性
* @author Katrina
*
*/
public class DemoTest {
private ClassPathXmlApplicationContext context;
@Before
public void beforeTest() {
//1.創建容器
context = new ClassPathXmlApplicationContext("demo-config.xml");
}
@After
public void afterTest() {
//3.關閉容器
context.close();
}
/**
* 定義一個無參數無返回值的public方法
*/
@Test
public void text1() {
//2.獲取類並測試
// Demo demo = (Demo) context.getBean("demo");
// Demo demo = (Demo) context.getBean("demo1"); //這一句並不是創建,這一句是從容器中取用
}
}
效果圖:
在test1上右擊選擇JUnit Test
part1:
part2:
part3:
懶加載,false
part3:
懶加載,true
空
part4:
懶加載,true
注意:修改demo-config.xml實現效果圖