Spring是基于Java的企业级应用开发的系列框架,来简化JavaEE企业级应用的开发,管理和集成各种框架。
Spring文档:https://docs.spring.io/spring/docs/5.1.9.RELEASE/spring-framework-reference/
Spring API:https://docs.spring.io/spring/docs/5.1.9.RELEASE/javadoc-api/
其中用来管理和集成各种框架的是Spring Framework,它由20个模块组成,总体上分为6个模块:Spring Core(核心子框架)、Spring Test(测试子框架)、Spring AOP(面向切面编程的子框架)、Spring Message(连接各种消息队列产品的创建)、Spring Web(开发Web的框架,实现VC层的框架)、Spring Data Access(简化DAO层的子框架,可以管理集成成各种DAO层框架如JDBC、JPA、Hibernate、Toplink等,没有MyBatis,MyBatis单独提供了MyBatis-Spring子框架)。
一、引入Spring Framework
Maven地址
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.8.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
二、Ioc
Ioc Container(Ioc 容器)是Spring 所有产品的核心,是管理各种对象的创建,销毁的对象。
项目中的所有对象(除Model类对象)基本上交给Spring Ioc的容器管理。
Ioc=Inverse of Control 反向控制,DI=Dependency Injection依赖注入,DI是Ioc的实现方式。Ioc 容器是实现Ioc和DI的对象。
1、创建
(1)Ioc的API
接口:ApplicationContext
实现类:ClassPathXmlApplicationContext 基于XML方式配置管理对象的容器实现类。
AnnotationConfigApplicationContext 基于JavaConfig类配置管理对象的实现类。
(2)XML方式
根目录下创建springcontext.xml(名字随意),通过MyBatis记录(一)的项目
<?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="userService" class="com.neusoft.busmis.security.service.impl.UserServiceImpl"></bean>
</beans>
创建:<bean name=”” class=”” 额外属性>
初始化:配置init-method/实现接口InitializingBean
调用:context.getBean(),进行方法的调用
销毁:配置destroy-method/实现DisposableBean接口。
或者用工厂模式来创建对象
package com.neusoft.busmis.security.fatory;
import com.neusoft.busmis.security.service.IUserService;
import com.neusoft.busmis.security.service.impl.UserServiceImpl;
public class ServiceFactory {
public static IUserService createUserService() {
return new UserServiceImpl();
}
public IUserService getUserService() {
return new UserServiceImpl();
}
}
<!-- 静态工厂 -->
<bean id="userservice" class="com.neusoft.busmis.security.fatory.ServiceFactory" factory-method="createUserService"></bean>
<!-- 动态工厂 -->
<bean id="servicefactory" class="com.neusoft.busmis.security.fatory.ServiceFactory"></bean>
<bean id="userservice2" class="com.neusoft.busmis.security.fatory.ServiceFactory" factory-bean="servicefactory" factory-method="createUserService"></bean>
测试,新建一个Java Class,创建容器对象,用ClassPathXmlApplicationContext用读取xml文件,然后用getBean来获取Ioc容器定义好的对象。
package com.neusoft.busmis.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.neusoft.busmis.security.model.UserModel;
import com.neusoft.busmis.security.service.IUserService;
public class TestSpring {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("springcontext.xml");
IUserService us = ac.getBean("userService", IUserService.class);
try {
UserModel um = us.getById("admin");
System.out.println(um.getUsername());
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出
可以通过getBeanDefinitionNames()方法获得ApplicationContext容器内所有Bean对象。
String[] names = ac.getBeanDefinitionNames();
for(String s:names)
System.out.println(s);
3、JavaConfig方式
通过编写使用@Configuration注解的配置类,完成Spring Ioc容器管理的Bean。
新建一个类,添加@Configuration注解,来表示这是个配置类,然后填写方法,在方法上添加@Bean注解,方法名就是Ben的ID。
package com.neusoft.busmis.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.neusoft.busmis.security.service.IUserService;
import com.neusoft.busmis.security.service.impl.UserServiceImpl;
@Configuration
public class SpringContextConfig {
@Bean
public IUserService getUserService() {
return new UserServiceImpl();
}
}
或者用工厂模式获取
//静态工厂
@Bean
public IUserService createUserService() {
return ServiceFactory.createUserService();
}
//动态工厂
@Bean
public IUserService getUserService() {
return new ServiceFactory().createUserService();
}
测试,用AnnotationConfigApplicationContext来读入配置类,然后一样用getBean来获取对象。
package com.neusoft.busmis.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.neusoft.busmis.config.SpringContextConfig;
import com.neusoft.busmis.security.model.UserModel;
import com.neusoft.busmis.security.service.IUserService;
public class TestSpring {
public static void main(String[] args) {
// ApplicationContext ac = new ClassPathXmlApplicationContext("springcontext.xml");
// IUserService us = ac.getBean("userService", IUserService.class);
// try {
// UserModel um = us.getById("admin");
// System.out.println(um.getUsername());
// } catch (Exception e) {
// e.printStackTrace();
// }
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringContextConfig.class);
IUserService us = ac.getBean("getUserService", IUserService.class);
try {
UserModel um = us.getById("admin");
System.out.println(um.getUsername());
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出
同种方式创建的对象是相等的,输出true;不同方式创建的对象是不相等的,输出false。
IUserService us = ac.getBean("userService", IUserService.class);
IUserService us1 = ac.getBean("userService", IUserService.class);
System.out.println(us==us1);
4、扫描方式
以上两种在需要创建的Bean对象多时,会很麻烦,所以有一种扫描的方式,在需要的注入Bean的类里添加注解,然后在配置文件里添加有注解的包,也可以实现。
常见的在类里添加的注解:
DAO层:@Repository
Service层:@Service
Controller层:@Controller,@RestController(发布REST API)
通用:@Component
当然,也不一定说在Service层一定要用@Service,只不过这样会更加规范。
在类里添加注解
@Service("userService")
public class UserServiceImpl implements IUserService {
(1)xml方式,在SpringContext.xml 添加<context:component-scan base-package="包名">,注意<beans>标签里需要添加相应的配置信息。
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.neusoft.busmis"></context:component-scan>
</beans>
(2)JavaConfig方式,添加@ComponentScan(basePackages = {"包名"}),有多个包,用逗号隔开。
package com.neusoft.busmis.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = {"com.neusoft.busmis"})
public class SpringContextConfig {
}
测试
package com.neusoft.busmis.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.neusoft.busmis.config.SpringContextConfig;
import com.neusoft.busmis.security.model.UserModel;
import com.neusoft.busmis.security.service.IUserService;
public class TestSpring {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("springcontext.xml");
IUserService us = ac.getBean("userService", IUserService.class);
IUserService us1 = ac.getBean("userService", IUserService.class);
System.out.println(us==us1);
try {
UserModel um = us.getById("admin");
System.out.println(um.getUsername());
} catch (Exception e) {
e.printStackTrace();
}
ApplicationContext acac = new AnnotationConfigApplicationContext(SpringContextConfig.class);
IUserService usac = acac.getBean("userService", IUserService.class);
System.out.println(us==usac);
try {
UserModel um = usac.getById("admin");
System.out.println(um.getUsername());
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出