Spring 指的是 Spring Framework(Spring 框架),它是个开源框架,Spring 持泛的应场景,它可以让 Java 企业级的应程序开发起来更简单。
1.1.1.1 什么是IoC容器?
容器是来容纳某种物品的装置。
IoC = Inversion of Control 翻译成中是"控制反转"的意思,控制权发的反转,不再是上级对象创建并控制下级对象了,是下级对象把注将当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发任何改变,当前类都是不受影响的,这就是 IoC 的实现思想。
Spring具备两个核心功能:将对象存到容器,从容器中取出对象。对象的创建和销毁的权利都交给 Spring 来管理了,它本身具备了存储对象和获取对象的能。
1.1.1.2 DI 概念说明
DI 是 Dependency Injection 的缩写,翻译成中是"依赖注"的意思。依赖注就是由 IoC 容器在运期间,动态地将某种依赖关系注到对象之中。所以,依赖注(DI)和控制反转(IoC)是从不同的度的描述的同件事情,就是指通过引 IoC 容器,利依赖关系注的式,实现对象之间的解耦,IoC 是"标"也是种思想,标和思想只是种指导原则,最终还是要有可的落地案, DI就属于具体的实现。
1.1.1.3 IoC容器和普通程序开发的区别
将对象存储在 IoC 容器相当于将以后可能的所有具制作好都放到仓库中,需要的时候直接取就了,完再把它放回到仓库。
new 对象的式相当于,每次需要工具了才现做,用完扔掉了也不会保存,下次再用的时候还得重新做。
1.2 Spring 创建和使用
1.2.1 创建 Spring 项目
使 Maven 式来创建个 Spring 项,创建 Spring 项和 Servlet 类似。
创建个 Maven 项
然后跳转到了这个页面:
添加 Spring 框架持
在项的 pom.xml 中添加 Spring 框架的持spring-context(spring 上下)和spring-beans(管理对 象的模块),xml 配置如下:
public class App {
public static void main(String[] args) {
// 1.得到 Spring 上下?对象
ApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
// 2.加载某个 bean
User user = (User) context.getBean("user");
// 3.调?相应的?法
System.out.println(user.sayHi("Java"));
}
}
1.2.4 使用注解读取和存储对象
配置扫描路径
配置下存储对象的扫描包路径,只有在被配置的包下且添加了注解的类才能被正确的识别并保存到 Spring 中。
在 Spring 框架的设计中,法注解 @Bean 要配合类注解才能将对象正常的存储到 Spring 容器中
使用@Bean存储 bean
@Component
public class Users {
@Bean
public User user1() {
User user = new User();
user.setId(1);
user.setName("Java");
return user;
}
}
读取bean
复制代码
public class Application {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
User user = (User) context.getBean("user1");
System.out.println(user.toString());
}
}
重命名 Bean
可以通过设置 name 属性给 Bean 对象进重命名。重
@Component
public class Users {
@Bean(name = {"u1"})
public User user1() {
User user = new User();
user.setId(1);
user.setName("Java");
return user;
}
}
命名的 name 其实是个数组,个 bean 可以有多个名字。
复制代码
@Bean(name = {"u1", "us1"}) public User user1() {
User user = new User();
user.setId(1);
user.setName("Java");
return user;
}
name={} 可以省略
复制代码
@Bean({"u1", "us1"})
public User user1() {
User user = new User();
user.setId(1);
user.setName("Java");
return user;
}
此时使 u1/us1 就可以获取到 User 对象了
复制代码
class App {
public static void main(String[] args) {
// 1.得到 spring 上下?
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// 2.得到某个 bean
User user = (User) context.getBean("u1");
// 3.调? bean ?法
System.out.println(user);
}
}
对象装配
获取 bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注。
<1> 属性注
属性注使 @Autowired 实现。
属性注的优点是简洁,使便;缺点是只能于 IoC 容器,如果是 IoC 容器不可,并且只 有在使的时候才会出现 NPE(空指针异常)。
示例:
Service 类的实现代码如下:
复制代码
import org.springframework.stereotype.Service;
@Service
public class UserService {
/**
* 根据 ID 获取?户数据
*
* @param id
* @return
*/
public User getUser(Integer id) {
// 伪代码,不连接数据库
User user = new User();
user.setId(id);
user.setName("Java-" + id);
return user;
}
}
@Component
public class Users {
// 第一个bean
@Bean
public User user1() {
User user = new User();
user.setId(1);
user.setName("Java");
return user;
}
// 第二个bean
@Bean
public User user2() {
User user = new User();
user.setId(2);
user.setName("MySQL");
return user;
}
}
在另个类中获取 User 对象:
复制代码
@Controller
public class UserController4 {
// 注?
@Resource
private User user;
public User getUser() {
return user;
}
}
执结果:
解决方法:
<<1>>使 @Resource(name="XXX")来指定bean
复制代码
@Controller
class UserController4 {
// 注?
@Resource(name = "user1")
private User user;
public User getUser() {
return user;
}
}
<2> 使 @Qualifier来指定bean
复制代码
@Controller
public class UserController5 {
// 注?
@Autowired
@Qualifier(value = "user2")
private User user;
public User getUser() {
return user;
}
}
2. Bean 详解
2.1 Bean的作用域
限定程序中变量的可范围叫做作域,或者说在源代码中定义变量的某个区域就叫做作域。
Bean 的作域是指 Bean 在 Spring 整个框架中的某种为模式。
Bean 有 6 种作域:singleton(单例作域),prototype(原型作域/多例作域), request(请求作域),session(回话作域),application(全局作域),websocket(HTTP WebSocket 作域)。后 4 种状态是 Spring MVC 中的值,在普通的 Spring 项中只有前两种。
@Component
public class Users {
@Bean
public User user1() {
User user = new User();
user.setId(1);
user.setName("Java"); // 【重点:名称是 Java】
return user;
}
}
A 户使时,进了修改操作:
复制代码
@Controller
public class BeanScopesController {
@Autowired
private User user1;
public User getUser1() {
User user = user1;
System.out.println("Bean 原 Name:" + user.getName());
user.setName("悟空"); // 【重点:进?了修改操作】
return user;
}
}
B 户再去使公共 Bean :
复制代码
@Controller
public class BeanScopesController2 {
@Autowired
private User user1;
public User getUser1() {
User user = user1;
return user;
}
}
查看 A 户和 B 户公共 Bean 的值:
复制代码
public class BeanScopesTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
BeanScopesController beanScopesController = context.getBean(BeanScopesController.class);
System.out.println("A 对象修改之后 Name:" + beanScopesController.getUser1().toString());
BeanScopesController2 beanScopesController2 = context.getBean(BeanScopesController2.class);
System.out.println("B 对象读取到的 Name:" + beanScopesController2.getUser1().toString());
}
}
在个http servlet Context中,定义个Bean实例,用于Web应的上下信息,如:记录个应的共享信息。限定SpringMVC中使。
application 是 Spring Web 中的作域,作于 Servlet 容器。singleton 是 Spring Core 的作域,singleton 作于 IoC 的容器。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
public class Users {
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Bean(name = "u1")
public User user1() {
User user = new User();
user.setId(1);
user.setName("Java"); // 【重点:名称是 Java】
return user;
}
}
2.2 Bean的生命周期
2.2.1 Spring 执行流程
2.2.2 Bean 的执行流程
启动 Spring 容器 --> 实例化 Bean(分配内存空间,从到有) --> Bean注册到Spring中(存操作) --> 将Bean装配到需要的类中(取操作)。