中国建设银行网站官网下载,天元建设集团有限公司北京分公司,青岛营销网站建设,wordpress模板 微信✏️作者#xff1a;银河罐头 #x1f4cb;系列专栏#xff1a;JavaEE #x1f332;“种一棵树最好的时间是十年前#xff0c;其次是现在” 目录 lombok的使用案例引入作用域定义singleton单例作用域prototype原型作用域(多例作用域)request请求作用域session会话作用域ap… ✏️作者银河罐头 系列专栏JavaEE “种一棵树最好的时间是十年前其次是现在” 目录 lombok的使用案例引入作用域定义singleton单例作用域prototype原型作用域(多例作用域)request请求作用域session会话作用域application全局作用域websocket 设置作用域Spring 执行流程Bean 的生命周期代码演示 lombok的使用
1.添加依赖
dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.26/versionscopeprovided/scope
/dependency2.在实体类使用 lombok 注解。
package com.java.demo.entity;
import lombok.Getter;
import lombok.Setter;//lombok
Setter
Getter
public class User {private int id;private String name;
}案例引入
package com.java.demo.entity;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
//lombok
Setter
Getter
ToString
public class User {private int id;private String name;
}package com.java.demo.component;
import com.java.demo.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;Component
public class UserBeans {Beanpublic User user(){User user new User();user.setId(1);user.setName(张三);return user;}
}package com.java.demo.controller;
import com.java.demo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;Controller
public class UserController {Autowiredprivate User user;public void printUser(){System.out.println(user);User myUser user;myUser.setName(悟空);System.out.println(myUser - myUser);System.out.println(user - user);}
}package com.java.demo.controller;
import com.java.demo.entity.User;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;Controller
public class UserController2 {Resourceprivate User user;public void printUser2(){System.out.println(user - user);}
}package com.java.demo;
import com.java.demo.controller.UserController;
import com.java.demo.controller.UserController2;
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-config.xml);UserController userController context.getBean(userController,UserController.class);userController.printUser();UserController2 userController2 context.getBean(userController2,UserController2.class);userController2.printUser2();}
}我的预期结果是
User(id1, name张三)
myUser - User(id1, name悟空)
user - User(id1, name张三)
user - User(id1, name张三)但运行之后结果是这样。
为什么会出现这种现象
原因是 Bean 的作用域(scope)默认是单例模式此 Bean 在 整个 spring 容器中只有一份。
作用域定义
Bean 的 6 种作用域
singleton单例作用域
无状态的 Bean 使用该作用域。无状态指的是Bean 对象的属性状态不需要更新。
spring 默认使用该作用域。
prototype原型作用域(多例作用域)
每次对该作用域下的 Bean 请求都是创建新的实例。获取及注入 Bean 都是新的对象实例。
通常有状态的 Bean 使用该作用域。
request请求作用域
每次 http 请求都会创建新的 Bean 实例。一次 http 请求和响应共享bean.
适用于 springMVC/spring Web
session会话作用域
每次 session 会话共享一个 Bean.
适用于 springMVC/spring Web
application全局作用域
application. 一个 http servlet context 共享一个 Bean.
适用于 springMVC/spring Web
websocket
限定 Spring WebSocket 中使用
注意在普通的 Spring 项⽬中只有前两种作用域。
设置作用域 回到之前的代码案例。
可以把 Bean 作用域 设置成 多例作用域。
要在存 Bean 之前就设置作用域。
package com.java.demo.component;
import com.java.demo.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;Component
public class UserBeans {BeanScope(prototype)public User user(){User user new User();user.setId(1);user.setName(张三);return user;}
}//第2种设置方式
Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)给出的提示也验证了前面所说的 spring core 项目 Bean 只能设置 2 种 作用域 singleton 和 prototype.
Scope 可以修饰方法也可以修饰 类。
Spring 执行流程
1.启动容器 加载配置文件。
2.根据配置完成 Bean 初始化。 扫描 base-package 目录底下所有类找到 加了五大类注解的类
3.把 Bean 存到 spring 容器中。 4.装配 Bean 的属性。(取 Bean)
如果 Bean 对象的属性里包含其他 Bean 对象可以通过 Autowired 、Resource 注入 Bean 的生命周期
1.实例化 Bean, 为 Bean 分配内存空间。
2.设置属性(Bean 装配和注入)
3.Bean初始化
各种通知如 BeanNameAware、BeanFactoryAware、 ApplicationContextAware 的接口方法初始化前置方法。初始化方法(设置了才会执行)1.注解方式PostConstruct 2. xml 方式init-method 方法初始化后置方法。
4.使用 Bean
5.销毁 Bean
代码演示
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contenthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsdcontent:component-scan base-packagecom.java.demo/content:component-scanbean idbeanComponentclasscom.java.demo.component.BeanComponent init-methodmyInit/bean
/beansApplicationContext 没有销毁方法。ClassPathXmlApplicationContext 有销毁方法。
package com.java.demo.component;
import org.springframework.beans.factory.BeanNameAware;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;public class BeanComponent implements BeanNameAware {Overridepublic void setBeanName(String s) {System.out.println(执行了通知 BeanName - s);}/*** XML 方式的初始化方法*/public void myInit(){System.out.println(XML 方式的初始化方法);}PostConstructpublic void postConstruct(){System.out.println(注解 方式的初始化方法);}public void sayHi(){System.out.println(执行 sayHi() 方法);}PreDestroypublic void doPreDestroy(){System.out.println(do PreDestroy);}
}package com.java.demo;
import com.java.demo.component.BeanComponent;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {ClassPathXmlApplicationContext context new ClassPathXmlApplicationContext(spring-config.xml);BeanComponent beanComponent context.getBean(beanComponent,BeanComponent.class);beanComponent.sayHi();context.destroy();}
}注解初始化方法 优先级高于 XML 初始化方法。
设置属性和初始化这两个步骤能颠倒吗
不能如果先初始化在初始化代码中如果调用了依赖的属性的方法就会报错(此时依赖的属性还没有注入)。
如果我想完善代码想看到更详细的 Bean 的生命周期流程能看到其他的通知初始化前置方法初始化后置方法。代码如下
package com.java.demo.component;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;public class BeanComponent implements BeanNameAware , BeanFactoryAware , ApplicationContextAware {Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println(执行了通知 ApplicationContext - applicationContext);}Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println(执行了通知 BeanFactory - beanFactory);}Overridepublic void setBeanName(String s) {System.out.println(执行了通知 BeanName - s);}/*** XML 方式的初始化方法*/public void myInit(){System.out.println(XML 方式的初始化方法);}PostConstructpublic void postConstruct(){System.out.println(注解 方式的初始化方法);}public void sayHi(){System.out.println(执行 sayHi() 方法);}PreDestroypublic void doPreDestroy(){System.out.println(do PreDestroy);}}package com.java.demo;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;public class MyBeanPostProcessor implements BeanPostProcessor {Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println(postProcessBeforeInitialization beanName 调用初始化前置方法);return bean;}Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println(postProcessAfterInitialization beanName 调用初始化后置方法);return bean;}
}?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contenthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsdcontent:component-scan base-packagecom.java.demo/content:component-scanbean idbeanComponentclasscom.java.demo.component.BeanComponent init-methodmyInit /beanbean idmyBeanPostProcessorclasscom.java.demo.MyBeanPostProcessor/bean
/beanspackage com.java.demo;
import com.java.demo.component.BeanComponent;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {ClassPathXmlApplicationContext context new ClassPathXmlApplicationContext(spring-config.xml);BeanComponent beanComponent context.getBean(beanComponent,BeanComponent.class);beanComponent.sayHi();context.destroy();//context.close();}
}