文章目录
- 1. 配置扫描路径
- 2. Spring五大类注解
- 3. Spring @Bean注解
- 对象装配
- 4. Bean对象在Spring中的作用域
- 5. Bean生命周期
1. 配置扫描路径
只有设置了扫描路径,其他的路径下注解不会被Spring扫描
这里设置路径为com.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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.beans"></context:component-scan>
</beans>
2. Spring五大类注解
@Controller控制器
@Sever服务
@Repoistory仓库
@Configuration配置
@Component组件
软件分层一般分为4层
@Configuration配置层-> @Controller控制层(前端参数校验)-> @Sever服务(数据组装,接口调用)-> @Repoistory(数据库操作,数据持久)
Spring五大类对应软件分的四层,项目工具类划分到@Component组件上。让代码的可读性提高,可以直观的判断这个类的业务用途。
五大类的联系:
- @Component可以看作其他四种注解的父类,其他四种注解都是依靠@Component实现。
使用注解将对象注册到Spring中,这个对象在获取时的名称与类名有关;
如果类名是大驼峰,获取Spring中的类名采用小驼峰获取
如果类名无规则,获取Spring中的类名和原类名相同
eg:User -> user获取 / USer -> USer获取
3. Spring @Bean注解
@Bean只能添加到方法上
@Bean注解需要配合五大类方法使用才可以将方法返回的对象储存到Spring中。
获取方法返回的对象名称就是方法名
package com.beans;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class beans {
@Bean
public user GetUser() {
user us = new user();
us.setId(1);
us.setName("123");
return us;
}
}
import com.beans.user;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
user u = context.getBean("GetUser", user.class);
System.out.println(u);
}
}
对象装配
从Spring中获取对象称为对象装配,将对象取出放入某个类中,有时也叫对象注入
Spring对象注入又三种方式:
- 属性注入 / 字段注入@Autowired
- 构造方法注入
- Setter注入
方式一:属性注入 / 字段注入@Autowired
package com.beans;
import org.springframework.stereotype.Controller;
@Controller
public class user {
private int id;
private String name;
@Override
public String toString() {
return "user{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
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;
}
}
package com.beans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class Test {
@Autowired
private user u;//将Spring中的user注入到这个类中
public void SayHi() {
u.setName("XXXX");
System.out.println(u);
}
}
方法二:通过构造方法注入对象
package com.beans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class Test2 {
private user u;
//通过构造方法注入,从Spring中获取user对象
@Autowired
public Test2(user u) {
this.u = u;
}
}
如果类中的构造方法只有一个是,@Autowired可以省略,多个构造函数不能省略
方法三:Setter注入
package com.beans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class Test2 {
private user u;
@Autowired
public void setU(user u) {
this.u = u;
}
}
三种注入方式的区别:
- 属性注入简单,但是只适用于IoC容器,通用性不好.
- setter注入:通用性没有构造方法通用性高
- 构造方法注入:通用性更好,可以保证对象初始化。
需要注意:JDK也提供了属性注入方式@Resource
在三种注入方式中除了构造方式注入,其他都可以使用@Resource替换@Autowired进行属性注入。
@Resource与@Autowired区别:
- 出身不同,@Resource来自JDK,@Autowired来自Spring
- 用法不同:@Resource不支持构造方法注入
- @Resource支持更多参数设置(name,type),@Autowired只支持required参数设置
重命名Bean:
可以通过设置name属性,给Bean对象进行重命名,多个name使用{}括起来
package com.beans;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class beans {
@Bean(name = {"UserInfo","User"})
public user GetUser() {
user us = new user();
us.setId(1);
us.setName("123");
return us;
}
}
@Bean命名规则:
- 没有设定name属性,bean默认名称就是方法名
- 如果设定了name属性,只能通过重命名的name的值来获取,不能使用方法名获取对象
@Bean将一个对象注入多次,可以通过下列方式解决
- 精确的描述bean的名称,指定不同Bean的name属性。
- 使用@Resource注解@Resource(name=“xxx”)
- 使用@Autowired+@Qualifier(value=“xxx”)指定具体对象,value可以省略
package com.beans;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class beans {
@Bean(name = "UserInfo")
public user GetUser() {
user us = new user();
us.setId(1);
us.setName("123");
return us;
}
@Bean(name = "UserInfo2")
public user GetUser2() {
user us = new user();
us.setId(2);
us.setName("456");
return us;
}
}
方式一:
package com.beans;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller
public class Test {
@Resource
private user UserInfo2;
private user UserInfo;//通过精确的描述bean的名称,指定不同Bean的name属性
public void SayHi() {
System.out.println(UserInfo2);
}
}
方式二:
package com.beans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller
public class Test {
@Resource(name = "UserInfo")
private user u;
public void SayHi() {
System.out.println(u);
}
}
方法三:
package com.beans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller
public class Test {
@Autowired
@Qualifier(value = "UserInfo2")
private user u;
public void SayHi() {
System.out.println(u);
}
}
4. Bean对象在Spring中的作用域
Bean对象在Spring中储存默认状态下是单例模式,不同人获取同类的对象是同一个
这样就会导致一个人修改了Spring中的对象,其他人获取到的对象就经过了修改。
Bean的作用域是指Bean在Spring中的某种行为模式
- singleton单例模型(默认)
- prototype原型模型(相当于多列模式,A修改不影响B用户使用这个对象)
- request请求作用域(SpringMVC项目,每一次请求共享一个对象)
- session会话作用域(SpringMVC项目,一个会话使用一个对象)
- application全局作用域(SpringMVC项目,一个项目中使用的对象)
- WebSocket作用域(HTTP web Socket作用域)
单例模型和全局作用域的区别:
- 单例作用域是Spring Core作用域,全局作用域是Spring WEB作用域
- 单例作用域适用于IoC容器,全局作用域适用于Servlet容器。
Bean对象作用域修改
@Scope(“prototype”)
或@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
package com.beans;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
public class beans {
@Bean(name = "UserInfo")
// @Scope("prototype")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public user GetUser() {
user us = new user();
us.setId(1);
us.setName("123");
return us;
}
}
5. Bean生命周期
Spring中的对象经历五个阶段
-
实例化,给Bean分配内存空间
-
设置属性,进行对象注入,防止后续操作出现空指针异常
-
初始化:
- 执行各种通知
- 执行初始化前置方法
- 执行构造方法,执行@PostConstruct或执行init-method方法
- 执行初始化的后置方法
-
使用Bean
-
销毁Bean:
- 执行@PreDestory方法
- 重写DisposableBean接口方法
- destory-method