第一:为什么要学习spring?学习spring能为我们在工作中的日常开发带来什么好处?
首先来了解一下spring;spring是一种开源的分层的相对于EJB来说的轻量级框架,它是为了解决企业应用开发的复杂性而创建的,因为在我们开发企业应用的时候,随着项目的复杂性的增加,类对象也会越来越多,如果我们还是通过new对象的方法来获取对象的话,那么类之间的耦合性就会不断提高,这样是不利于程序的维护的。
使用spring带来的好处是:spring使用基本的javaBean来完成由EJB完成的任务,可以是程序简单化,增强程序的可测试性和减少耦合性。spring最核心的两个组件是IOC和AOP,也就是翻转控制和面向切面。
第二:由于spring的官网下载地址中,之前版本的spring 下载很难找到,这里为了方便下载;将地址复制如下‘
Spring介绍 https://blog.csdn.net/qq_38526573/article/details/86408267;这是一个博客,里面有5之前的spring版本供我们学习;如果要下载5版本的话可以在官网直接下载。
第三:最简单的spring使用以及几种获取类对象的方法介绍:
方法一:里面包含了两种不同的方式
1,导包:先介绍几个获取对象需要用到的核心包:为什么是这几个包在之后会通过解析源码的方式的到体现;这里只是为了阶段性的介绍获取类对象 的时候需要用到的核心包,不涉及其他的包。在spring中总共有20个核心包
,
2,创建一个类:
package com.sxt;
/**
* @author ASUS
*
*/
public class Person {
private int age;
private String name;
public Person() {
System.out.println("我是无参构造!!");
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void say() {
System.out.println("hello>>>>");
}
}
3,创建一个xml文件:
<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">
先将beans的配置信息配置进入;然后在xml中声明类Person
<!-- 注册类信息 -->
<bean class="com.sxt.Person" id="person"></bean>
</beans>
所谓的声明就是自己创建类的信息告诉spring容器,这里可以通过给类设置id,name属性,反射三种方式告诉spring容器帮助我们去创建类对象。
4,创建一个测试类:
现在在测试类中只用第一种方式来获取类对象:
方式一:通过初始化spring容器,来加载配置文件,根据配置文件来初始化获取ApplicationContext对象
ApplicationContext ac=new ClassPathXmlApplicationContext("application.xml");
Person person=(Person) ac.getBean("person");
person.say();
注意这个方式的执行:会在加载配置文件的时候获取ApplicationContext对象就会直接实例化类的无参构造方法;也就是执行了第一句之后,该类的无参构造方法就已经被实例化了。
方式二:这种方式已经过时,但是我们还是看到这两者的区别的:
BeanFactory bf=new XmlBeanFactory(new ClassPathResource("application.xml"));
Person P = bf.getBean(Person.class);
P.say();
从这里我们可以看出这两种方式的区别:第一种方式通过ApplicationContext对象来获取类对象的方法,在加载完配置文件的时候,配置文件中的所有的类的对象就已经被创建了;而第二种方式通过BeanFactory来获取类对象的方法,在加载完配置文件的时候,配置文件中的类对象并没有被创建,而只有这个请求到达之后,才会创建。这两个方式好比在饭店吃饭,一个是已经预先炒好了菜,等请求到来的时候直接上菜;而第二种方式则是客人的请求到来的时候才开始做菜。
这两种方式里面又包括了三种方法来获取对象:
可以利用id
name属性
这两种方法没有什么区别;而且也没有什么可以去区分的
和反射。
5,通过源码来了解这两种方式的不同:
方法二:通过静态工厂注入的方式:
方法三:通过动态工厂注入的方式:
6类对象中的属性注入:前面只是单纯获取一个类的对象,并没有将类里面的属性赋值
第一种是通过构造注入的方式:这种方式必须有带参构造方法
在注册文件中注册属性:
<bean class="com.sxt.Person" >
<!-- 通过构造注属性信息 -->
<constructor-arg name="age" value="13"/>
<constructor-arg name="name" value="张三"/>
</bean>
在测试类中可看到注入的属性信息:
第二种是通过设置注入的方式:
在配置文件中设置属性信息:
<bean class="com.sxt.Person" >
<!-- 通过setter注入属性信息 -->
<property name="age" value="33"/>
<property name="name" value="王五"/>
</bean>
可以在测试类中看到结果:
上面这两种方式还是比较简单的,我们在java基础中的封装中就讲过类似的;只不过那个时候不是通过配置文件注入成员属性的而已,但是也是通过带参构造和get,set方法给成员变量赋值!!!!
第三种:p名称空间注入
第四种:对象注入:
/**
*
*/
package com.sxt;
/**
* @author ASUS
*
*/
public class Person {
private int age;
private String name;
private Cat cat;
public Person() {
System.out.println("我是无参构造!!");
}
//使用构造注入必须有带参构造方法
/*public Person(int age,String name) {
this.age=age;
this.name=name;
}*/
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void say() {
System.out.println("hello>>>>");
}
@Override
public String toString() {
return "Person [age=" + age + ", name=" + name + ", cat=" + cat + "]";
}
/**
* @return the cat
*/
public Cat getCat() {
return cat;
}
/**
* @param cat the cat to set
*/
public void setCat(Cat cat) {
this.cat = cat;
}
}
假如说一个对象中有另一个对象,那么如何获取该对象的属性信息呢?
这是另一个对象:
/**
*
*/
package com.sxt;
/**
* @author ASUS
*
*/
public class Cat {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Cat [id=" + id + ", name=" + name + "]";
}
}
可知:在Person中要有该对象的set方法和重写的tostring方法
在配置文件中:
<bean class="com.sxt.Person" >
<property name="age" value="23"/>
<property name="name" value="李四"/>
<!-- 对象注入 -->
<property name="cat" ref="catId"></property>
</bean >
<bean class="com.sxt.Cat" id="catId">
<property name="id" value="34"/>
<property name="name" value="小明"></property>
</bean>
我们通过引用的方式将Cat对象的属性信息引入到Person对象中;当对象较多的时候使用set方法设置属性信息较为方便;
可以在测试类中看到结果:
第五中集合和数组注入:
Person类:
/**
*
*/
package com.sxt;
import java.util.Arrays;
/**
* @author ASUS
*
*/
public class Person {
private int age;
private String name;
//private Cat cat;
private Cat[] cats;
@Override
public String toString() {
return "Person [age=" + age + ", name=" + name + ", cats=" + Arrays.toString(cats) + "]";
}
public Person() {
System.out.println("我是无参构造!!");
}
//使用构造注入必须有带参构造方法
/*public Person(int age,String name) {
this.age=age;
this.name=name;
}*/
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void say() {
System.out.println("hello>>>>");
}
/**
* @return the cats
*/
public Cat[] getCats() {
return cats;
}
/**
* @param cats the cats to set
*/
public void setCats(Cat[] cats) {
this.cats = cats;
}
}
Cat类:
/**
*
*/
package com.sxt;
/**
* @author ASUS
*
*/
public class Cat {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Cat [id=" + id + ", name=" + name + "]";
}
}
配置文件的属性注入:
<bean class="com.sxt.Person">
<property name="age" value="223"/>
<property name="name" value="赵柳"/>
<!-- 数组注入 -->
<property name="cats">
<array>
<bean class="com.sxt.Cat">
<property name="id" value="233"/>
<property name="name" value="小明"/>
</bean>
<bean class="com.sxt.Cat">
<property name="id" value="244"/>
<property name="name" value="小红"/>
</bean>
</array>
</property>
</bean>
在测试类中可以看到结果:
集合注入:
Person类:
/**
*
*/
package com.sxt;
import java.util.List;
/**
* @author ASUS
*
*/
public class Person {
private int age;
private String name;
//private Cat cat;
private List<String> games;
@Override
public String toString() {
return "Person [age=" + age + ", name=" + name + ", games=" + games + "]";
}
public Person() {
System.out.println("我是无参构造!!");
}
//使用构造注入必须有带参构造方法
/*public Person(int age,String name) {
this.age=age;
this.name=name;
}*/
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void say() {
System.out.println("hello>>>>");
}
/**
* @return the games
*/
public List<String> getGames() {
return games;
}
/**
* @param games the games to set
*/
public void setGames(List<String> games) {
this.games = games;
}
}
这里要注意必须有set方法,利用设值注入的时候;还要重写tostring方法
配置文件:
<bean class="com.sxt.Person">
<property name="age" value="23"/>
<property name="name" value="赵琦"/>
<property name="games">
<list>
<value>LOL</value>
<value>CS</value>
<value>DFS</value>
</list>
</property>
</bean>
在测试类中看到结果:
map注入:
Person类:
/**
*
*/
package com.sxt;
import java.util.List;
import java.util.Map;
/**
* @author ASUS
*
*/
public class Person {
private int age;
private String name;
//private Cat cat;
private Map<String, Object> map;
@Override
public String toString() {
return "Person [age=" + age + ", name=" + name + ", map=" + map + "]";
}
public Person() {
System.out.println("我是无参构造!!");
}
//使用构造注入必须有带参构造方法
/*public Person(int age,String name) {
this.age=age;
this.name=name;
}*/
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void say() {
System.out.println("hello>>>>");
}
/**
* @return the map
*/
public Map<String, Object> getMap() {
return map;
}
/**
* @param map the map to set
*/
public void setMap(Map<String, Object> map) {
this.map = map;
}
}
配置文件:
<bean class="com.sxt.Person">
<property name="age" value="34"/>
<property name="name" value="李四"/>
<property name="map">
<map>
<entry key="语文" value="44"/>
<entry key="数学" value="55"/>
<entry key="英语" value="66"/>
</map>
</property>
</bean>
在测试类中看到结果:
props注入:
Person类:
/**
*
*/
package com.sxt;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* @author ASUS
*
*/
public class Person {
private int age;
private String name;
//private Cat cat;
//private Map<String, Object> map;
private Properties properties;
@Override
public String toString() {
return "Person [age=" + age + ", name=" + name + ", properties=" + properties + "]";
}
public Person() {
System.out.println("我是无参构造!!");
}
//使用构造注入必须有带参构造方法
/*public Person(int age,String name) {
this.age=age;
this.name=name;
}*/
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void say() {
System.out.println("hello>>>>");
}
/**
* @return the properties
*/
public Properties getProperties() {
return properties;
}
/**
* @param properties the properties to set
*/
public void setProperties(Properties properties) {
this.properties = properties;
}
}
配置文件:
<bean class="com.sxt.Person">
<property name="age" value="34"/>
<property name="name" value="李四"/>
<property name="properties">
<props>
<prop key="usernmae">admin</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
在测试类中看到结果: