单例和多例
单例: 在内存中只能有一份
多例: 在内存中可能有多分
Spring
管理的对象默认是 单例的
也就是创建的对象是同一个对象 引用的是地址值
在配置Spring
管理容器目录文件里面
默认管理的上方有一个 Scope
注解默认值是 singleton
表示 使用的 单例模式 创建的对象
@Configuration
@ComponentScan("com.jt")
public class SpringConfig {
@Bean
@Scope("singleton")//默认 状态 单例模式
public User user(){
return new User();
}
}
设置为多例将默认值 设置为 prototype
@Configuration
@ComponentScan("com.jt")
public class SpringConfig {
@Bean
@Scope("prototype")// 管理对象为 多例模式
public User user(){
return new User();
}
}
懒加载
如果Spring
容器创建 对象立即创建则该加载方式为 立即加载 容器启动时候直接创建对象
如果Spring
容器创建在被使用的时候才创建对象 称为懒加载 使用的时候创建才 创建对象
使用的注解是 @Lazy
注解
@Configuration
@ComponentScan("com.jt")
public class SpringConfig {
@Bean
@Lazy
public User user(){
return new User();
}
}
多例与懒加载的关系
在 单例模式 中控制 懒加载 才有效
在 多例模式 中使用 默认是 懒加载 所以添不添加懒加载 没有效果
Spring 对象生命周期管理
一个对象 从创建到消亡 分为四个阶段
生命周期方法 就是从创建到消亡的 干预
称之为 回调函数 / 钩子函数 / 接口方法
如果要控制生命周期需要在 控制的 对象类里 方法上 添加注解
@PostConstruct
对象创建的时候立即调用
@PreDestroy
在容器销毁的时候 对象销毁 进行调用
@Component
public class Person {
public Person(){//无参构造
System.out.println("张三 呱呱坠地");
}
@PostConstruct //在对象 创建之后 立即调用
public void init(){
System.out.println("张三 成为 少年");
}
//业务方法
public void doWork(){
System.out.println("迎娶 白富美");
}
@PreDestroy // 对象 销毁时 进行调用
public void clear(){
System.out.println("装入 盒子");
}
}
使用
@Test
public void testDemo3(){
// 需要改变为 具体的实现类对象
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
Person person = context.getBean(Person.class);
//doWork 方法 是具体的业务逻辑
person.doWork();
//容器销毁 创建的对象销毁
// 将容器 关闭
context.close();
}
依赖注入
依赖注入 Dependency Injection
简称 DI
完全交给Spring
框架来完成
在对象中如果需要使用属性注入 使用
@Autowired
注解
可以将Spring
容器中的对象 自动注入到属性中
注入方式:
1. 默认按照 类型注入 如果注入的属性是接口 自动注入 接口的实现类
2. 按照 名称注入(key
)
注意
注入的前提是 一定要被 Spring
容器进行管理
也就是说 注入的属性所在的当前类 需要被Spring
容器管理
例如有一个抽象类Pet
public interface Pet {
void hello();
}
有一个Cat
实现了
@Component // 将对象 交给Spring 容器进行管理 存储的 key 是cat value 是 对象
public class Cat implements Pet {
@Override
public void hello() {
System.out.println("我是 喵喵喵");
}
}
需要注入到User
里的pet
属性 添加@AutoWired
注解
但是类型是抽象类 所以自动去找 下面的实现类 Cat
@Component // 将User 交给Spring 容器进行管理
public class User {
// 将当前接口的实现类自动注入
@Autowired
private Pet pet;
public void say(){
pet.hello();
}
}
如果注入的类型是抽象类 并有两个抽象类
那么需要加入一个注解
@Qualifier("参数")
该注解不能单独使用必须配合AutoWired
进行使用
里面的参数是对象的 id
开头小写
如有一个Dog
类实现了 上方的Pet
@Component
public class Dog implements Pet {
@Override
public void hello() {
System.out.println("我是 汪汪汪");
}
}
那么在User
类里注入Dog
类
必须是 类名 并且首字母小写
@Component // 将User 交给Spring 容器进行管理
public class User {
// 将当前接口的实现类自动注入
@Autowired
@Qualifier("dog")
private Pet pet;
public void say(){
pet.hello();
}
}
另一种实现方式
使用@Resource
注解 将上方两个合并了
默认不写参数时 使用类型 进行注入
加入参数时 @Resource(name="参数")
使用固定的参数 对应的类 进行注入
但是不推荐使用
MVC 实际思想
是一种设计上的模式
M: model 指的是业务模型
V: view 指的是用户界面
C: control 指的是控制层
实现了Java
类的分层 并实现松耦合
分层说明:
1. 控制层 :Controller 与前端页面交互的
2. 业务层 :Service 编写业务逻辑
3. 持久层 :Mapper 实现数据库的相关操作
Spring
提供了这些分层的注解
控制层 :Controller @Controller
注解
业务层 :Service @Service
注解
持久层 :Mapper @Repository
注解
首先将具体的底层逻辑代码交给Mapper
通过业务层Service
取调用 Mapper
再通过 控制层 Controller
取调用 Service
关于传参
@value
注解 可以直接为 基本类型赋值
比如:
@Value("狗蛋")
private String userName;
因为 耦合性较高 需要用另一种方式
对象的属性一般是业务数据 如果需要为业务数据赋值则
一般采用properties
配置文件 更加灵活
在resources
目录里面添加 后缀.properties
需要更改软件的字符集为 utf-8
里面的参数是 key=value
等号连接 中间不要添加多余的空格
如:
name=狗蛋
不加引号
系统里面占用了 username
绕开这个名称
使用 :
@Repository
@PropertySource(value = "classpath:/user.properties",encoding = "UTF-8") // 里面的参数是classpath:/ 是固定语法 classpath:/ 代表resources根目录 user.properties 是里面的指定文件
public class UserMapperImpl implements UserMapper {
// springel 表达式 取值方式 缩写 spel表达式
//通过 key动态获取spring容器里的value
@Value("${userName}")
private String userName;
@Override
public void addUser() {
System.out.println("新增用户"+userName);
}
}
@PropertySource
指定配置文件
里面的参数是classpath:/
是固定语法
代表resources
根目录