zoukankan      html  css  js  c++  java
  • Spring快速入门

    引言

    最近几天一直在忙着学习数据结构和算法,关于JavaEE的框架也有一阵子没更新了。那么今天就来聊一聊Spring框架吧,针对该框架写一篇快速入门的文章。

    Spring简介

    Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。

    • 目的:解决企业应用开发的复杂性
    • 功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
    • 范围:任何Java应用

    Spring是一个轻量级控制反转(IOC)和面向切面(AOP)的容器框架。

    配置Bean

    首先来说一说在Spring框架中如何去配置Bean。
    通过一个简单案例感受一下:
    首先得导入Spring框架的jar包,然后创建一个类:

    package com.itcast.spring.bean;
    
    public class HelloWorld {
    
    	private String name;
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void hello() {
    		System.out.println("hello:" + name);
    	}
    }
    

    在传统的写法中,我们要想调用HelloWorld类的hello()方法,我们需要手动创建HelloWorld的实例,然后调用setName()方法给name赋值,接着调用hello()方法。但是有了Spring框架之后,对于对象的创建和属性的赋值都不需要我们操心,框架能够帮助我们完成。所以接下来创建Spring框架的配置文件applicationContext.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 id="helloWorld" class="com.itcast.spring.bean.HelloWorld">
    		<property name="name" value="Spring"></property>
    	</bean>
    	
    </beans>
    

    对于这段简单的配置,可以解释一下。bean是beans下的一个子节点,配置的是一个bean类的信息,然后是bean节点下的属性:

    • id:标识容器中的bean,id是唯一的
    • class:bean的全类名,因为框架是通过反射的方式在IOC容器中创建bean的实例,所以你需要提供类的全路径,这在很多框架中都能得到体现

    然后是property,该节点配置的是bean类中的属性信息,name即为属性名,但是需要注意的是,这个name值是根据setXXX()方法进行匹配的,如果没有setXXX()方法或者setXXX()方法和类中的属性名不一致,将会导致异常产生。而value就是属性的值。
    配置好后,我们编写测试代码:

    public static void main(String[] args) {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    		HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld");
    		helloWorld.hello();
    }
    

    首先通过ClassPathXmlApplicationContext去构造ApplicationContext 对象,传入配置文件名,接着通过getBean()方法得到HelloWorld实例,传入的是在配置文件中bean的id属性值。
    运行结果:

    hello:Spring
    

    需要注意的是,在bean类中你必须提供一个无参的构造方法,因为反射的实现需要无参构造。
    到这里,一个入门的Spring案例就完成了。

    Spring容器

    接下来,我们细细地研究一下。
    在SpringIOC容器读取bean配置创建bean实例之前,必须对它进行实例化,只有在容器实例化后,才可以从IOC容器中获取bean实例并使用。
    在Spring中提供了两种类型的IOC容器实现:

    1. BeanFactory:IOC容器的基本实现
      BeanFactory是Spring框架的基础设施,面向Spring本身
    2. ApplicationContext:提供了更多的高级特性,是BeanFactory的子接口
      ApplicationContext面向使用Spring框架的开发者,几乎所有的应用场合都直接使用ApplicationContext而非底层的BeanFactory

    但无论使用何种方式,配置文件的写法都是一样的。
    ApplicationContext是BeanFactory的子接口,它有两个实现类:

    1. ClassPathXmlApplicationContext:从类路径下加载配置文件
    2. FileSystemXmlApplicationContext:从文件系统中加载配置文件

    所以获得ApplicationContext的实例可以有两种方式,刚才的案例中使用的就是第一种方式。

    获得了Spring容器后,我们是如何去获得bean实例的呢?
    通过getBean()方法:
    在这里插入图片描述
    可以看到,ApplicationContext提供了多个getBean()方法的重载,所以对于bean实例的获取,除了通过id属性值获取以外,还可以通过bean的类型获取:

    public static void main(String[] args) {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    		HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
    		helloWorld.hello();
    }
    

    这样也能获取到bean的实例,而且有一个好处就是不用强制类型转换了。

    属性值的注入

    在Spring框架中,有两种方式可以对bean类的属性进行赋值:

    1. 属性注入
      属性注入在开始的案例中已经使用到了,就是通过bean节点下的property节点进行注入,它通过setXXX()方法注入属性值,属性注入是实例应用开发中最常用的注入方式
    2. 构造方法注入
      构造方法注入顾名思义就是通过构造方法注入属性值,它通过bean节点下的constructor-arg节点进行注入

    对于构造方法注入属性值,有必要单独提取出来讲解一下,我们来看一个案例。
    创建一个bean类:

    package com.itcast.spring.bean;
    
    public class Car {
    
    	private String brand;
    	private String corp;
    	private double price;
    	private int maxSpeed;
    	
    	public Car(String brand, String corp, double price) {
    		super();
    		this.brand = brand;
    		this.corp = corp;
    		this.price = price;
    	}
    
    	@Override
    	public String toString() {
    		return "Car [brand=" + brand + ", corp=" + corp + ", price=" + price + ", maxSpeed=" + maxSpeed + "]";
    	}
    }
    

    然后配置一下:

    <?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的属性值 -->
    	<bean id="car" class="com.itcast.spring.bean.Car">
    		<constructor-arg value="Audi"></constructor-arg>
    		<constructor-arg value="ShangHai"></constructor-arg>
    		<constructor-arg value="250000"></constructor-arg>
    	</bean>
    </beans>
    

    接下来编写测试代码:

    public static void main(String[] args) {
    	ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    	Car car = (Car) ctx.getBean("car");
    	System.out.println(car);
    }
    

    运行结果:

    Car [brand=Audi, corp=ShangHai, price=250000.0, maxSpeed=0]
    

    因为是通过构造方法注入属性值,所以可以不需要setXXX()方法,从配置中可以知道,属性值是通过配置的顺序进行注入的,那么接下来我们修改一下Car类:

    package com.itcast.spring.bean;
    
    public class Car {
    
    	private String brand;
    	private String corp;
    	private double price;
    	private int maxSpeed;
    
    	public Car(String brand, String corp, double price) {
    		super();
    		this.brand = brand;
    		this.corp = corp;
    		this.price = price;
    	}
    
    	public Car(String brand, String corp, int maxSpeed) {
    		super();
    		this.brand = brand;
    		this.corp = corp;
    		this.maxSpeed = maxSpeed;
    	}
    
    	@Override
    	public String toString() {
    		return "Car [brand=" + brand + ", corp=" + corp + ", price=" + price + ", maxSpeed=" + maxSpeed + "]";
    	}
    }
    

    我们在Car类中新增了一个构造方法,然后我们重新配置一下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.xsd">
    
    	<bean id="car2" class="com.itcast.spring.bean.Car">
    		<constructor-arg value="BMW"></constructor-arg>
    		<constructor-arg value="BeiJing"></constructor-arg>
    		<constructor-arg value="240"></constructor-arg>
    	</bean>
    </beans>
    

    我们想通过这三个属性值来得到一个Car的实例,接下来编写测试代码:

    public static void main(String[] args) {
    	ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    	Car car = (Car) ctx.getBean("car2");
    	System.out.println(car);
    }
    

    运行结果:

    Car [brand=BMW, corp=BeiJing, price=240.0, maxSpeed=0]
    

    问题就出现了,我明明是想通过第二个构造方法构造对象,传入的240是maxSpeed的值,但它仍然使用了第一个构造方法,所以仅仅靠参数顺序来注入是不合理的。
    不过不用担心,Spring为我们提供了类型匹配来区分不同的构造方法,修改配置文件:

    <?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 id="car2" class="com.itcast.spring.bean.Car">
    		<constructor-arg value="BMW" type="java.lang.String"></constructor-arg>
    		<constructor-arg value="BeiJing"
    			type="java.lang.String"></constructor-arg>
    		<constructor-arg value="240" type="int"></constructor-arg>
    	</bean>
    </beans>
    

    其它地方不用修改,重新运行一下测试代码,结果如下:

    Car [brand=BMW, corp=BeiJing, price=0.0, maxSpeed=240]
    

    这样就达到了我们想要的结果。
    对于属性值的注入,还可以通过子节点下的value节点进行注入,效果是一样的。

    引用类型属性值的注入

    对字面值的注入有了一定的了解之后,我们单独看一下引用类型的属性值该如何注入:
    先创建一个bean类:

    package com.itcast.spring.bean;
    
    public class Person {
    
    	private String name;
    	private int age;
    	private Car car;
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getAge() {
    		return age;
    	}
    
    	public void setAge(int age) {
    		this.age = age;
    	}
    
    	public Car getCar() {
    		return car;
    	}
    
    	public void setCar(Car car) {
    		this.car = car;
    	}
    
    	@Override
    	public String toString() {
    		return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
    	}
    }
    

    在配置文件中配置一下Person类:

    <?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 id="car2" class="com.itcast.spring.bean.Car">
    		<constructor-arg value="BMW" type="java.lang.String"></constructor-arg>
    		<constructor-arg value="BeiJing"
    			type="java.lang.String"></constructor-arg>
    		<constructor-arg value="240" type="int"></constructor-arg>
    	</bean>
    	
    	<bean id="person" class="com.itcast.spring.bean.Person">
    		<property name="name" value="Tony"></property>
    		<property name="age" value="18"></property>
    		<property name="car" ref="car2"></property>
    	</bean>
    </beans>
    

    对于引用类型Car,我们可以通过property节点的ref属性指向对car的引用,因为上面我配置了一个id为car2的bean,所以这里直接通过id引用指向它。
    编写测试代码:

    public static void main(String[] args) {
    	ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    	Person person = (Person) ctx.getBean("person");
    	System.out.println(person);
    }
    

    运行效果:

    Person [name=Tony, age=18, car=Car [brand=BMW, corp=BeiJing, price=0.0, maxSpeed=240]]
    

    和上面类似,也可以使用子节点ref进行配置。

    <bean id="person" class="com.itcast.spring.bean.Person">
    		<property name="name" value="Tony"></property>
    		<property name="age" value="18"></property>
    		<property name="car">
    			<ref bean="car2"/>
    		</property>
    </bean>
    

    我们还可以在属性或构造器里包含一个bean的声明,这样的bean称为内部bean,无法被外部访问。

    <bean id="person" class="com.itcast.spring.bean.Person">
    		<property name="name" value="Tony"></property>
    		<property name="age" value="18"></property>
    		<property name="car">
    			<bean class="com.itcast.spring.bean.Car">
    				<constructor-arg value="Audi" type="java.lang.String"></constructor-arg>
    				<constructor-arg value="ShangHai" type="java.lang.String"></constructor-arg>
    				<constructor-arg value="250000" type="double"></constructor-arg>
    			</bean>
    		</property>
    </bean>
    

    Spring和Struts、Hibernate框架一样,也支持级联属性。所以我们还可以通过级联属性赋值。

    <property name="car.price" value="150000"></property>
    

    可以通过这样的方式给Car类的属性赋值。

    集合属性值注入

    在引用类型中,又有一个特殊的群体,集合。包括Set、List、Map。
    修改Person类代码:

    package com.itcast.spring.bean;
    
    import java.util.List;
    
    public class Person {
    
    	private String name;
    	private int age;
    	private List<Car> cars;
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getAge() {
    		return age;
    	}
    
    	public void setAge(int age) {
    		this.age = age;
    	}
    
    	@Override
    	public String toString() {
    		return "Person [name=" + name + ", age=" + age + ", cars=" + cars + "]";
    	}
    
    	public List<Car> getCars() {
    		return cars;
    	}
    
    	public void setCars(List<Car> cars) {
    		this.cars = cars;
    	}
    }
    

    其中有一个集合类型Car,该如何在配置文件中进行配置呢?

    <?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的属性值 -->
    	<bean id="car" class="com.itcast.spring.bean.Car">
    		<constructor-arg value="Audi"></constructor-arg>
    		<constructor-arg value="ShangHai"></constructor-arg>
    		<constructor-arg value="250000"></constructor-arg>
    	</bean>
    
    	<bean id="car2" class="com.itcast.spring.bean.Car">
    		<constructor-arg value="BMW" type="java.lang.String"></constructor-arg>
    		<constructor-arg value="BeiJing" type="java.lang.String"></constructor-arg>
    		<constructor-arg value="240" type="int"></constructor-arg>
    	</bean>
    	
    	<!-- 如何配置集合属性 -->
    	<bean id="person2" class="com.itcast.spring.bean.Person">
    		<property name="name" value="Jack"></property>
    		<property name="age" value="20"></property>
    		<property name="cars" >
    			<list>
    				<ref bean="car"/>
    				<ref bean="car2"/>
    			</list>
    		</property>
    	</bean>
    </beans>
    

    编写测试代码:

    public static void main(String[] args) {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    		Person person = (Person) ctx.getBean("person2");
    		System.out.println(person);
    }
    

    运行结果:

    Person [name=Jack, age=20, cars=[Car [brand=Audi, corp=ShangHai, price=250000.0, maxSpeed=0], Car [brand=BMW, corp=BeiJing, price=150000.0, maxSpeed=240]]]
    

    对于Set和Map集合,Spring提供了set标签和map标签进行配置,配置原理相同,不作重复介绍。Map集合会有点特殊,因为它是以键值对的方式存储的,所以它是通过Map节点下的子节点entry进行配置的,entry节点包含key和value-ref属性,也简单配置一下给大家看看吧。

    <map>
    	<entry key="aa" value-ref="car"></entry>
    	<entry key="bb" value-ref="car2"></entry>
    </map>
    

    属性文件值注入

    还有一种特殊类型,Properties,就是我们熟知的配置文件,在Spring中,同样可以通过配置直接将值注入到该属性中,看一个案例你们就会明白。
    创建一个bane类:

    package com.itcast.spring.bean;
    
    import java.util.Properties;
    
    public class DataSource {
    
    	private Properties properties;
    
    	public Properties getProperties() {
    		return properties;
    	}
    
    	public void setProperties(Properties properties) {
    		this.properties = properties;
    	}
    
    	@Override
    	public String toString() {
    		return "DataSource [properties=" + properties + "]";
    	}
    }
    

    然后对该类进行配置:

    <?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 id="dataSource" class="com.itcast.spring.bean.collection.DataSource">
    		<property name="properties">
    			<props>
    				<prop key="user">root</prop>
    				<prop key="password">123456</prop>
    				<prop key="url">jdbc:mysql:///test</prop>
    				<prop key="driver">com.mysql.jdbc.Driver</prop>
    			</props>
    		</property>
    	</bean>
    </beans>
    

    配置完成后,编写测试代码:

    public static void main(String[] args) {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    		DataSource dataSource = (DataSource) ctx.getBean("dataSource");
    		System.out.println(dataSource);
    }
    

    运行结果:

    DataSource [properties={user=root, url=jdbc:mysql:///test, password=123456, driver=com.mysql.jdbc.Driver}]
    

    实现过程非常简单,这样就将对数据库的配置注入到Properties属性中,关于对数据库的操作就可以通过这样进行封装。

    鉴于是对Spring的快速入门,所以也没有去深入地介绍Spring的一些内容,关于Spring的快速入门,就说到这里,接下来还会出几篇Spring高级或者Spring一些其它的知识点。

  • 相关阅读:
    ionic localstorage
    angular 中文鏈接
    把jqmobi 變成jQuery 的插件 從此使用jQuery
    jqmobi 的一些設置
    ionic ngcordova map 地圖
    ionic pull to refresh 下拉更新頁面
    json 對象的序列化
    鍵盤彈出,頁面佈局被推上去了.....
    Cordova V3.0.0中config.xml配置文件的iOS Configuration
    android ios 只能輸入數字 不能輸入小數點的 函數 cordova
  • 原文地址:https://www.cnblogs.com/blizzawang/p/11411528.html
Copyright © 2011-2022 走看看