学Java,不懂Spring框架?还不快快戳进来!(一步步带你创建属于你自己的Spring程序)属性注入,Spring的配置,bean作用域。放心,小白也能看的懂啦~
文章目录
紧接我的上一篇博客看不懂的可以去瞅两眼~
1、利用构造器进行属性注入的其他方式
1.1、通过下标赋值
<!--第一种,下标赋值!-->
<bean id="user" class="com.gang.pojo.Hello">
<constructor-arg index="0" value="范孟钢"/>
</bean>
1.2、通过类型赋值
<!--第二种方式:通过类型创建,不建议使用!-->
<bean id="user" class="com.gang.pojo.Hello">
<constructor-arg type="java.lang.String" value="刚子"/>
</bean>
1.3、通过参数名赋值
这种方法呢,就是我上一篇博客中所使用的方法,建议大家使用这种方法!
<!--第三种,直接通过参数名来设置-->
<bean id="us)er" class="com.gang.pojo.Hello">
<constructor-arg name="name" value="饭缸"/>
</bean>
2、Spring的一些花里胡哨的配置
2.1、别名(低配版)
<!--别名,如果添加了别名,我们也可以使用别名获取到这个对象
比如现在,我用hello2或者hello都可以获取这个对象!
-->
<alias name="hello" alias="hello2"/>
<bean id="hello" class="com.gang.pojo.Hello">
<constructor-arg name="name" value="Spring"/>
</bean>
2.2、别名(高配版)
<!--
id : bean 的唯一标识符,也就是相当于我们学的对象名
class : bean 对象所对应的全限定名 : 包名 + 类型
name :也是别名,而且name 可以同时取多个别名 中间用空格或者分号隔开就行
-->
<bean id="hello" class="com.gang.pojo.Hello" name="hello3 hello4;hello5">
<constructor-arg name="name" value="Spring"/>
</bean>
2.3、import
因为大家开发项目一般都是团队开发的,这时候每个人都有自己的配置文件,这时候就需要import了,将其他配置文件导入到一个总的中!
例如:
- 张三 bean1.xml
- 李四 bean2.xml
- 王五 bean3.xml
- 总项目 applicationContext.xml
只需要在applicationContext.xml中导入他们三个即可!
<import resource="beans1.xml"/>
<import resource="beans2.xml"/>
<import resource="beans3.xml"/>
那么使用的时候,直接使用总的配置就可以了~
3、set方式注入(各种数据类型的注入方法)
一般我们都会使用set方法进行注入!上一篇博客中我们的第一个Spring程序中只进行了String类型数据类型的注入的写法,接下来,就给大家演示一下各种数据类型的不同写法吧!
测试环境的搭建~
3.1、首先创建两个实体类
第一个:地址类。参数就简单了,一个名称就完了~(其实创建它是为了获得一个复杂的类型)
package com.gang.pojo;
/*
Description:地址实体类
Author:32259
Time:2020二月2020/2/2315:05
*/
public class Address {
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
private String address;
}
第二个:学生类。学生他有很多属性,也有地址(就上面那个类),实际测试对象!
package com.gang.pojo;
/*
Description:学生实体类
Author:32259
Time:2020二月2020/2/2315:05
*/
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 ;// null 没媳妇,早恋不太好!
private 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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", address=" + address.getAddress() +
", books=" + Arrays.toString(books) +
", list=" + list +
", map=" + map +
", set=" + set +
", wife='" + wife + '\'' +
", info=" + info +
'}';
}
}
3.2、然后我们创建一个bean.xml文件
活学活用,将这个配置文件用import导入总的配置文件!
<?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="getAddress" class="com.gang.pojo.Address">
<property name="address" value="西安"/>
</bean>
<!--
当我们发现他的属性是一个类 类型的时候,我们要把这个类的对象创建好,然后用ref引入进去 仔细看!
-->
<bean id="student" class="com.gang.pojo.Student">
<property name="name" value="范孟钢"/>
<property name="address" ref="getAddress"/>
<property name="books">
<array>
<value>论一个打野的自我修养</value>
<value>来自峡谷蓝buff的哭诉</value>
<value>小兵也有大理想</value>
</array>
</property>
<property name="list">
<list>
<value>令狄大人的头疼的案件</value>
<value>元芳的108个看法</value>
<value>赔钱虎的赔本买卖</value>
</list>
</property>
<property name="map">
<map>
<entry key="震惊!峡谷惊现猥琐男" value="原来是穿了爱与正义的小金金呐~"/>
<entry key="谁偷了庄周的鲲?" value="此时,一只扛着鲲不愿透露姓名的韩信从旁边走过~"/>
<entry key="阿离怎么走哪都带把伞?" value="可能是被雨淋怕了吧~"/>
</map>
</property>
<property name="set">
<set>
<value>中二少年快乐的一天</value>
<value>好歹我也是最完美的英雄</value>
<value>没有控制的我却成了大热门</value>
</set>
</property>
<property name="wife">
<null/>
</property>
<property name="info">
<props>
<prop key="id">100</prop>
<prop key="name">僵硬</prop>
<prop key="money">10000</prop>
</props>
</property>
</bean>
</beans>
3.3、最后编写测试类
import com.gang.pojo.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void testStudent(){
//注意:我这里加载的是总文件,但是我已经将我写的bean.xml导入进来啦~
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) context.getBean("student");
System.out.println(student);
}
}
3.4、执行程序,查看结果,提出问题找出答案
好了,所有的属性都被注入成功啦~
大家可能会好奇,我这里明明是使用set方法进行注入的,也就是使用无参构造创建的对象,怎么会打印一句 “有参构造被执行了!”了呢?而不是“无参构造被执行了!”?
注意:那是因为我的xml中有通过构造注入的bean,而它的有参构造中有System.out.println("有参构造被执行了!")
这么一句代码!前面说了,对象是由Spring创建的,他不管你用不用,他已经创造好了,就在IOC容器里搁着,所以会调用那个类中的有参构造!就是我不管你用不用,我都会创建一个!自然会打印这句话了~
而至于为什么没打印“无参构造被执行了!”这句话,很简单,因为我没在无参构造中写System.out.println("无参构造被执行了!")
这行代码!
看到这里,大家是不是对IOC的理解更加深刻了呢~
4、聊一下bean的作用域
这里聊一下singleton和prototype,其余的都是web开发中使用!
4.1、单例模式:singleton(Spring默认机制)
好,我们测试一下
1.改一下上面的xml文件,加一个scope属性即可,里面选择singleton
当然,你不写的话也是可以的,它默认就是单例模式
<?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="getAddress" class="com.gang.pojo.Address">
<property name="address" value="西安"/>
</bean>
<!--bean的scope属性 表示作用域
singleton 单例的 在容器中只有一个对象(默认的)
prototype 每次都会创建一个新对象-->
<bean id="student" class="com.gang.pojo.Student" scope="singleton">
<property name="name" value="范孟钢"/>
<property name="address" ref="getAddress"/>
<property name="books">
<array>
<value>论一个打野的自我修养</value>
<value>来自峡谷蓝buff的哭诉</value>
<value>小兵也有大理想</value>
</array>
</property>
<property name="list">
<list>
<value>令狄大人的头疼的案件</value>
<value>元芳的108个看法</value>
<value>赔钱虎的赔本买卖</value>
</list>
</property>
<property name="map">
<map>
<entry key="震惊!峡谷惊现猥琐男" value="原来是穿了爱与正义的小金金呐~"/>
<entry key="谁偷了庄周的鲲?" value="此时,一只扛着鲲不愿透露姓名的韩信从旁边走过~"/>
<entry key="阿离怎么走哪都带把伞?" value="可能是被雨淋怕了吧~"/>
</map>
</property>
<property name="set">
<set>
<value>中二少年快乐的一天</value>
<value>好歹我也是最完美的英雄</value>
<value>没有控制的我却成了大热门</value>
</set>
</property>
<property name="wife">
<null/>
</property>
<property name="info">
<props>
<prop key="id">100</prop>
<prop key="name">僵硬</prop>
<prop key="money">10000</prop>
</props>
</property>
</bean>
</beans>
2.改一下测试类
import com.gang.pojo.Student;
import com.gang.pojo.User;
import com.gang.service.impl.UserServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void testStudent(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) context.getBean("student");
Student student1 = (Student) context.getBean("student");
System.out.println(student.hashCode());
System.out.println(student1.hashCode());
// System.out.println(student);
}
}
执行程序,看结果!
大家可以发现,我们虽然是从容器中拿了两次对象,这两个对象的哈希值是一样的,就说明,这个对象只被创建了一份,就是单例模式。
4.2、原型模式:(prototype)每次从容器中get的时候,都会产生一个新对象!
1.好,首先把上面配置中的scope改为prototype!
这里只重写了这一行代码,偷个懒,哈哈哈哈~
<bean id="student" class="com.gang.pojo.Student" scope="prototype">
2.测试类不用改了
3.运行程序,看结果~
OK,在这里我们发现哈希值明显不一样,这就说明你每次拿的时候都会拿到一个新的对象!
看完了之后,大家有什么收获呢?欢迎评论~