新建一个Maven web项目。
在pom.xml中加入JDK编译版本的插件
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
Spring 容器需要依赖4个包,context,core,beans,spel.
在http://mvnrepository.com/找到对应的坐标,这里使用的是4.2.4版本。
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
</dependencies>
导入之后为了使项目不报错,maven update一下。可能会有如下错误:
接下来需要一个配置文件applicationContext.xml,这个配置文件放到src/main/resources下边,创建一个xml。这个xml文件名字叫什么都可以,一般默认applicationContext.xml
有了xml之后第一步找xml的约束,下边两种都可以,一般使用第二种xsd的写法。
Referencing the schemas
To switch over from the DTD-style to the new XML Schema-style, you need to make the following change.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<!-- bean definitions here -->
</beans>
The equivalent file in the XML Schema-style would be…
<?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 definitions here -->
</beans>
将第二段xml的代码粘贴到applicationContext.xml当中。约束头复制粘贴就好,不要手敲。
有了约束之后,搞个对象加载一下。
在eclipse里边安装Spring Config Editor插件。在eclipse marketplace里搜索sts(spring tool suite)。安装这个插件之后在编辑配置文件的时候会有提示。
这种下载安装非常慢,也可以手动下载下来copy进eclipse里(离线安装直接覆盖features和plugins两个文件夹)。
怎样获取一个容器:
在spring的api里提供了一种容器叫ApplicationContext
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserInterface.java
package com.aa.spring.demo1;
public interface UserInterface {
public void sayHello();
}
UserInterfaceImpl.java
package com.aa.spring.demo1;
public class UserInterfaceImpl implements UserInterface {
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Override
public void sayHello() {
System.out.println("hello spring" + userName);
}
}
SpringBeansTest.java
package com.aa.spring;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.aa.spring.demo1.UserInterface;
import com.aa.spring.demo1.UserInterfaceImpl;
public class SpringBeansTest {
/**
* spring入门案例
* @throws Exception
*/
@Test
public void getUser() throws Exception {
//以前写代码是这个酱紫:
/* UserInterfaceImpl interface1 = new UserInterfaceImpl();
interface1.sayHello();
interface1.setUserName("张三");*/
//对象通过反射由容器创建出来。
//获取容器(第一步)
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//有了容器以后从容器里面取对象
UserInterface bean = (UserInterface) context.getBean("UserInterfaceImpl");
bean.sayHello();//如果执行成功说明对象获取成功
}
}
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 definitions here -->
<bean id="UserInterfaceImpl" class="com.aa.spring.demo1.UserInterfaceImpl">
<!-- spring给属性赋值,底层还是调用的set方法-->
<property name="userName" value="张三"></property>
</bean>
</beans>
容器创建的3种方式
ApplicationContext是一个接口,它还不是最大的接口,他上边还有好多接口。最大的接口叫BeanFactory。按Ctrl+Shift+T找到BeanFactory。打开之后按Ctrl+T可以查看它所有的子接口和子实现类。箭头所指的是刚才使用的ApplicationContext接口,然后new了一个ClassPathXmlApplicationContext类。在它的下边还有一个实现类FileSystemXmlApplicationContext。使用它也可以创建容器。
第2种方式和第1种不同的是传进去的配置文件使用的是绝对路径。而第一种使用的是相对路径。平时使用第一种方式最多。
第3种方式已经过时了,但是也可以用。之所以过时是因为它使用的是懒加载的模式。
用maven最大的好处就是它可以帮我们把源码全down下来。
SpringBeansTest.java
package com.aa.spring;
import org.junit.Test;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import com.aa.spring.demo1.UserInterface;
import com.aa.spring.demo1.UserInterfaceImpl;
public class SpringBeansTest {
/**
* spring入门案例
* 第一种创建容器的方式使用的最多
*/
@Test
public void getUser() throws Exception {
//以前写代码是这个酱紫:
/* UserInterfaceImpl interface1 = new UserInterfaceImpl();
interface1.sayHello();
interface1.setUserName("张三");*/
//对象通过反射由容器创建出来。
//获取容器(第一步) 这里使用的是相对路径
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//有了容器以后从容器里面取对象
UserInterface bean = (UserInterface) context.getBean("UserInterfaceImpl");
bean.sayHello();//如果执行成功说明对象获取成功
}
/**
* 容器创建的第二种方式UserInterfaceImpl
* 这种方式用的不多,传的是绝对路径,用的最多的是第一种方式
*/
@Test
public void getFileSystemContainer() throws Exception {
//和第一种用的ClassPathXmlApplicationContext不同的是这里使用 的是绝对路径
ApplicationContext context = new FileSystemXmlApplicationContext("F:\\win10c\\oxygen-workspace\\springDay01\\src\\main\\resources\\applicationContext.xml");
UserInterfaceImpl bean = (UserInterfaceImpl) context.getBean("UserInterfaceImpl");//参数是配置文件里的id
bean.sayHello();
}
/**
* 容器创建的第三种方式,已经过时了,不再使用
* 之所以过时,是因为它是懒加载模式
* 在applicationContext里定义了很多bean,没有用到的就不会加载。
* 但是ClassPathXmlApplicationContext是只要获取容器,就把applicationContext里面所有的bean全都加载,所有的对象都创建
*/
@Test
public void getXmlContainer() throws Exception {
ClassPathResource resource = new ClassPathResource("applicationContext.xml");
XmlBeanFactory beanFactory = new XmlBeanFactory(resource);
}
}
创建对象的3种方式:1默认构造器,2静态工厂,3实例工厂。
静态工厂,实例工厂便于我们初始化对象的时候做其它的操作。
<?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">
<!-- 1.使用默认构造器方式创建对象 -->
<bean id="userBean" class="com.aa.spring.demo2.UserBean">
<property name="username" value="李四"></property>
</bean>
<!-- 2.通过静态工厂来创建对象 -->
<bean id="userBean2Factory" class="com.aa.spring.demo2.UserBean2Factory" factory-method="getUserBean2">
</bean>
<!-- 3.通过实例工厂来创建对象 -->
<bean id="userBean3Factory" class="com.aa.spring.demo2.UserBean3Factory"></bean>
<!-- 指定factory-bean和factory-method之后就不会通过反射去加载对象,会调用factory-bean和factory-method指定的"com.aa.spring.demo2.UserBean3Factory"去加载对象 -->
<bean id="userBean3" class="com.aa.spring.demo2.UserBean3" factory-bean="userBean3Factory" factory-method="getUserBean3"></bean>
</beans>
spring与web的整合
到这里虽然解决了创建对象交给了spring对工程进行了解耦,但是频繁的去创建创建对象的容器也是一个问题。除了可以在request和session域对象中存值,还可以在最大的servletContext域对象中存值。每次在tomcat启动的时候项目就会创建一个servletContext对象,可以在当中getAttribute和setAttribute进行存对象和获取对象。写一个监听器(javaweb的3大组件之一),监听tomcat的启动,一旦tomcat启动,就马上创建一个spring容器,也就是ApplicationContext。创建完成之后把这个容器放进ServletContext里面。这个监听器不需要自己写,spring已经提供好了。spring中有一个包叫spring-web,就是用来做spring与web整合的。还有一个servlet-api包。
在pom.xml中添加下边两个依赖的jar包
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
在用eclipse写web程序的时候不需要加servlet包,因为创建以后eclipse会自动加入servlet包,而用maven写的项目,需要手动加入servlet包。provided表示开发和测试的时候需要,打包的时候不要。
在web.xml中写监听器,spring-web包里已经提供了一个监听器,叫ContextLoaderListener:
安装spring的sts插件会有提示。
这里的location是配置文件的路径,classpath表示资源文件夹下
<!-- 这个也是sts插件做的 -->
<!-- 监听器 -->
<!-- needed for ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- classpath表示文件夹下有一个applicationContext.xml -->
<!-- 它会自动到resource下找applicationContext.xml -->
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
这样监听器就有了。
WebApplicationContext context = (WebApplicationContext) request.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
CollectProperty bean = (CollectProperty) context.getBean("collectProperty");
System.out.println(bean.toString());
在servlet中通过getAttribute得到spring容器。这样就避免了spring容器的频繁创建。
spring当中的注解
需要导入spring-aop包
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
然后在spring的配置文件中加入scheme
<?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:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
开启注解
<!-- context:component-scan 表示我们需要扫描哪个包下面的注解 -->
<context:component-scan base-package="com.aa.spring.demo7"></context:component-scan>