Java从入门到入土之Spring-IoC篇

1.Spring是什么
  Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。
2.Spring的优点
  ①、方便解耦,简化开发
  通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。有了Spring,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
  
  ②、AOP编程的支持
  通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。
  
  ③、声明式事务的支持
  在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。
  
  ④、方便程序的测试
  可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而是随手可做的事情。例如:Spring对Junit4支持,可以通过注解方便的测试Spring程序。
  
  ⑤、方便集成各种优秀框架
  Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如Struts,Hibernate、Hessian、Quartz)等的直接支持。

⑥、降低Java EE API的使用难度
  Spring对很多难用的Java EE API(如JDBC,JavaMail,远程调用等)提供了一个薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。

⑦、Java 源码是经典学习范例
  Spring的源码设计精妙、结构清晰、匠心独运,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。Spring框架源码无疑是Java技术的最佳实践范例。如果想在短时间内迅速提高自己的Java技术水平和应用开发水平,学习和研究Spring源码将会使你收到意想不到的效果。
3.Spring需要的jar包
在这里插入图片描述
4.spring配置文件
pojo实体类

package com.pojo;

public class Student {

	private int sid;
	private String name;
	public Student() {
		super();
	}
	public Student(int sid, String name) {
		super();
		this.sid = sid;
		this.name = name;
	}
	public int getSid() {
		return sid;
	}
	public void setSid(int sid) {
		this.sid = sid;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Student{" +
				"sid=" + sid +
				", name='" + name + '\'' +
				'}';
	}
}

IOC(控制反转)
构造函数创建Bean
配置文件

<?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-2.5.xsd">
    <!--通过构造器创建Bean
    id 唯一标识,可以任意命名一般为类的首字母小写
    class 类的全地址-->
    <bean id="student1" class="com.pojo.Student">
        <!--初始化时注入属性,需要类生成set方法-->
        <property name="name" value="张三"/>
        <property name="sid" value="1"/>
    </bean>
   <!--用带参的构造器给属性初始化-->
    <bean id="student2" class="com.pojo.Student" scope="singleton">
        <constructor-arg index="0" value="1"></constructor-arg>
        <constructor-arg index="1" value="jack"></constructor-arg>
    </bean>
</beans>

测试类

public class Test1 {

    public static void main(String[] args) {
        /*创建spring容器对象*/
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        /*通过spring容器获取student对象*/
        Student student1 = (Student) ac.getBean("student1");
        System.out.println(student1);
        Student student2 = (Student) ac.getBean("student2");
        System.out.println(student2);

    }
}

运行结果

七月 25, 2019 9:30:10 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31221be2: startup date [Thu Jul 25 09:30:10 CST 2019]; root of context hierarchy
七月 25, 2019 9:30:10 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
Student{sid=1, name='张三'}
Student{sid=1, name='jack'}

静态工厂方法创建Bean
静态工厂类

public class StaticStudentFactory {

    private static Student student;

    public static Student getStudent(int sid,String name) {
        student = new Student(sid,name);
        return student;
    }

}

配置文件

<?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-2.5.xsd">
    <!--通过静态工厂创建Bean
    id 唯一标识,可以任意命名一般为类的首字母小写
    class 类的全地址
    factory-method 获取实例化对象的方法-->
    <bean id="student3" class="com.factory.StaticStudentFactory" factory-method="getStudent">
        <!--方法需要的参数
        index 第几个参数,从0开始
        value 注入参数的值-->
        <constructor-arg index="0" value="1"/>
        <constructor-arg index="1" value="Tom"/>
    </bean>
</beans>

测试类

public class Test1 {

    public static void main(String[] args) {
        /*创建spring容器对象*/
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        /*通过spring容器获取student对象*/
        Student student3 = (Student) ac.getBean("student3");
        System.out.println(student3);
    }
}

行结果

七月 25, 2019 9:34:47 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31221be2: startup date [Thu Jul 25 09:34:47 CST 2019]; root of context hierarchy
七月 25, 2019 9:34:48 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
Student{sid=1, name='Tom'}

Process finished with exit code 0

实例化工厂
实例化工厂类

public class InstanceStudentFactory {

    private Student student;

    public Student getStudent(int sid,String name){
        student =  new Student(sid,name);
        return student;
    }
}

配置文件

<?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-2.5.xsd">
    <!--通过实例化工厂创建Bean-->
    <!--将实例化工厂InstanceStudentFactory交给spring管理-->
    <bean id="StudentFactory" class="com.factory.InstanceStudentFactory">
    </bean>
    <!--factory-bean 工厂Bean 引用上面交给spring管理的工厂
    factory-method 工厂中生产student的方法-->
    <bean id="student4" factory-bean="StudentFactory" factory-method="getStudent">
        <!--方法需要的参数
       index 第几个参数,从0开始
       value 注入参数的值-->
        <constructor-arg index="0" value="1"/>
        <constructor-arg index="1" value="roes"/>
    </bean>
</beans>

测试类

public class Test1 {

    public static void main(String[] args) {
        /*创建spring容器对象*/
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        /*通过spring容器获取student对象*/
        Student student4 = (Student) ac.getBean("student4");
        System.out.println(student4);
    }
}

运行结果

七月 25, 2019 9:44:53 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31221be2: startup date [Thu Jul 25 09:44:53 CST 2019]; root of context hierarchy
七月 25, 2019 9:44:53 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
Student{sid=1, name='roes'}

Process finished with exit code 0

使用注解
配置文件

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
  	 <!--开启spring扫描,可能在那些包下有注解,多个使用,隔开。也可以直接写com-->
    <context:component-scan base-package="com.pojo"></context:component-scan>
</beans>

需要导入context的xsd

package com.pojo;

import org.springframework.stereotype.Component;

/*value 获取Bean的id
* 可以省略直接写@Component 则id为类名首字母小写*/
@Component(value = "abc")
public class Student {

	private int sid;
	private String name;
	public Student() {
		super();
	}
	public Student(int sid, String name) {
		super();
		this.sid = sid;
		this.name = name;
	}
	public int getSid() {
		return sid;
	}
	public void setSid(int sid) {
		this.sid = sid;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Student{" +
				"sid=" + sid +
				", name='" + name + '\'' +
				'}';
	}
}

只需要在类的上面加上@Component注解。value 获取Bean的id 可以省略直接写@Component 则id为类名首字母小写
DI(依赖注入)
pojo实体类
Dog类只有一个String name的属性

package com.pojo;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class People {
    private int id;

    private String name;

    private List<String> list;

    private Set<String> set;

    private Map<String,String> map;

    private Properties prop;

    private Dog dog;

    public People(int id, String name, List<String> list, Set<String> set, Map<String, String> map, Properties prop, Dog dog) {
        this.id = id;
        this.name = name;
        this.list = list;
        this.set = set;
        this.map = map;
        this.prop = prop;
        this.dog = dog;
    }

    public People() {
    }

    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;
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public Set<String> getSet() {
        return set;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public Map<String, String> getMap() {
        return map;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public Properties getProp() {
        return prop;
    }

    public void setProp(Properties prop) {
        this.prop = prop;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    @Override
    public String toString() {
        return "People{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", list=" + list +
                ", set=" + set +
                ", map=" + map +
                ", prop=" + prop +
                ", dog=" + dog +
                '}';
    }
}

通过Set方法注入属性
配置文件

<?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"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
    <!--加载外部文件,交给spring管理,用于给properties属性注入-->
    <bean id="lq" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="locations">
            <list>
                <value>classpath*:lq.properties</value>
            </list>
        </property>
    </bean>
    <!--将Dog类交给spring管理-->
    <bean id="dog" class="com.pojo.Dog">
        <property name="name" value="来福"/>
    </bean>
    <!--通过属性的set方法注入-->
    <bean id="people" class="com.pojo.People">
        <!--String类型和基本类型注入
        name 属性名
        value 给属性赋值-->
        <property name="id" value="1"></property>
        <property name="name" value="李青 "></property>
        <!--list类型注入
        name 属性名
        value 一个元素-->
        <property name="list">
            <list>
                <value>打野</value>
                <value>上单</value>
                <value>辅助</value>
                <value>中单</value>
            </list>
        </property>
        <!--set类型注入
        name 属性名
        value 一个元素-->
        <property name="set">
            <set>
                <value>aaa</value>
                <value>bbb</value>
                <value>ccc</value>
                <value>aaa</value>
            </set>
        </property>
        <!--map类型注入
        name 属性名
        entry 一个元素-->
        <property name="map">
            <map >
                <entry key="装备1" value="无尽之刃"></entry>
                <entry key="装备2" value="饮血剑"></entry>
                <entry key="装备3" value="绿叉"></entry>
                <entry key="装备4" value="羊刀"></entry>
            </map>
        </property>
        <!--用ref引用propertiesBean的id-->
        <property name="prop" ref="lq"></property>
        <!--自定义类直接饮用其Bean的id-->
        <property name="dog" ref="dog"></property>
    </bean>
</beans>

外部文件lq.propert

k1=aaa
k2=bbb
k3=ccc
k4=ddd

测试类

package com.test;

import com.pojo.People;
import com.pojo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test1 {

    public static void main(String[] args) {
        /*创建spring容器对象*/
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        /*通过spring容器获取student对象*/
        People people = (People) ac.getBean("people");
        System.out.println(people);
    }
}

运行结果

七月 25, 2019 11:12:03 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31221be2: startup date [Thu Jul 25 11:12:03 CST 2019]; root of context hierarchy
七月 25, 2019 11:12:03 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
七月 25, 2019 11:12:03 上午 org.springframework.beans.factory.config.PropertiesFactoryBean loadProperties
信息: Loading properties file from URL [file:/C:/Users/lx/Desktop/01spring/out/production/01spring/lq.properties]
People{id=1, name='李青 ', list=[打野, 上单, 辅助, 中单], set=[aaa, bbb, ccc], map={装备1=无尽之刃, 装备2=饮血剑, 装备3=绿叉, 装备4=羊刀}, prop={k4=ddd, k3=ccc, k2=bbb, k1=aaa}, dog=Dog{name='来福'}}

Process finished with exit code 0

构造器注入属性

<?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"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
    <!--加载外部文件,交给spring管理,用于给properties属性注入-->
    <bean id="lq" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="locations">
            <list>
                <value>classpath*:lq.properties</value>
            </list>
        </property>
    </bean>
    <!--将Dog类交给spring管理-->
    <bean id="dog" class="com.pojo.Dog">
        <property name="name" value="来福"/>
    </bean>
    <!--通过构造器注入-->
    <bean id="people" class="com.pojo.People">
        <!--按照构造器中属性的排列顺序,从0开始,一一对应。几个属性可以调换顺序但是index value一定要对应
        index 第几个参数
        valus 参数赋值-->
        <constructor-arg index="0" value="1"/>
        <constructor-arg index="1" value="李青"/>
        <!--
        type 参数的类型,需要全称-->
        <constructor-arg index="2" type="java.util.List">
            <list>
                <value>打野</value>
                <value>上单</value>
                <value>辅助</value>
                <value>中单</value>
            </list>
        </constructor-arg>
        <constructor-arg index="3" type="java.util.Set">
            <set>
                <value>aaa</value>
                <value>bbb</value>
                <value>ccc</value>
                <value>aaa</value>
            </set>
        </constructor-arg>
        <constructor-arg index="4" type="java.util.Map">
            <map >
                <entry key="装备1" value="无尽之刃"></entry>
                <entry key="装备2" value="饮血剑"></entry>
                <entry key="装备3" value="绿叉"></entry>
                <entry key="装备4" value="羊刀"></entry>
            </map>
        </constructor-arg>
        <!--properties文件,自定义类交给spring管理后可以直接引用,ref=引用id-->
        <constructor-arg index="5" type="java.util.Properties" ref="lq">
        </constructor-arg>
        <constructor-arg type="com.pojo.Dog" ref="dog"></constructor-arg>
    </bean>
</beans>

运行结果

七月 25, 2019 11:19:56 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31221be2: startup date [Thu Jul 25 11:19:56 CST 2019]; root of context hierarchy
七月 25, 2019 11:19:56 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
七月 25, 2019 11:19:57 上午 org.springframework.beans.factory.config.PropertiesFactoryBean loadProperties
信息: Loading properties file from URL [file:/C:/Users/lx/Desktop/01spring/out/production/01spring/lq.properties]
People{id=1, name='李青', list=[打野, 上单, 辅助, 中单], set=[aaa, bbb, ccc], map={装备1=无尽之刃, 装备2=饮血剑, 装备3=绿叉, 装备4=羊刀}, prop={k4=ddd, k3=ccc, k2=bbb, k1=aaa}, dog=Dog{name='来福'}}

Process finished with exit code 0

通过注解实现注入
配置文件

<?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 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"
    default-autowire="byName">
    <!--在beans的default-autowire属性中设置全局自动装配方式为byName,也可以针对某个Bean单独设置-->
    <!--开启com.pojo包的扫描-->
    <context:component-scan base-package="com.pojo"/>
</beans>

pojo实体类

package com.pojo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class Demo {
    /*@Autowired是根据类型自动装配的,加上@Qualifier则可根据byName的方式自动装配,其中@Qualifier不能单独使用。
     *@Qualifier(value = "student") 括号中的value属性必须有不然会报错
     *@Resource如有指定的name属性,先按该属性进行byName方式查找装配;其次再进行默认的byName方式进行装配;        以上都不成功,则按byType的方式自动装配。@Resource(name="student")括号中可不写。
     *@Autowired,@Qualifier是spring提供的注解 @Resource是Java提供的注解 */
    @Autowired
    @Qualifier(value = "student")
    @Resource(name="student")
    private Student student;

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    @Override
    public String toString() {
        return "Demo{" +
                "student=" + student +
                '}';
    }
}

运行结果

七月 25, 2019 11:47:56 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31221be2: startup date [Thu Jul 25 11:47:56 CST 2019]; root of context hierarchy
七月 25, 2019 11:47:56 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
Demo{student=Student{sid=0, name='null'}}

Process finished with exit code 0

student被初始化,没有初始化属性。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值