Raison : Bean scope est en mode singleton par défaut, ce qui signifie que tout le monde utilise le même objet ! Lorsque nous avons appris le mode singleton auparavant, nous savions tous que l'utilisation de singletons peut améliorer les performances dans une large mesure, donc la portée de Beans in Spring est également le mode singleton par défaut.
@Component public class Users { @Bean public User user1(){ User user = new User(); user.setId(1); user.setName("Java"); return user; } }
@Component public class Bean1 { @Autowired private User user; public User getUser(){ System.out.println("Bean1对象未修改name之前 : "+user); user.setName("C++"); return user; } }
@Component public class Bean2 { @Autowired private User user; public User getUser(){ return user; } }
public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); Bean1 bean1 = context.getBean("bean1",Bean1.class); System.out.println(bean1.getUser()); Bean2 bean2 = context.getBean("bean2",Bean2.class); System.out.println(bean2.getUser()); } }
Créez une seule copie de la même ressource, économisant de l'espace
Pas besoin de créer et de détruire trop d'objets, et la vitesse d'exécution est améliorée
La portée est généralement comprise comme : limiter la plage de variables disponibles dans un programme est appelé portée, ou une certaine zone du code source où les variables sont définies est appelée portée.
⽽La portée de Bea
fait référence à un certain modèle de comportement de Bean
dans tout le cadre de Spring
, tel que singleton< / code> La portée Singleton signifie que <code>Bean
n'a qu'une seule copie dans l'ensemble du Spring
. Elle est partagée globalement, donc lorsque d'autres modifient cette valeur, après cela, ce qu'une autre personne lit est la. valeur modifiée. Bea
的作⽤域是指Bean
在 Spring
整个框架中的某种⾏为模式,⽐如singleton
单例作⽤域,就表
示Bean
在整个Spring
中只有⼀份,它是全局共享的,那么当其他⼈修改了这个值之后,那么另⼀个
⼈读取到的就是被修改的值。
在Spring中,bean 的作用域被称为是行为模式,因为在Spring看来,单例模式,就是一种行为,意味着在整个Spring中bean只能存在一份。
singleton:单例作⽤域
prototype:原型作⽤域(多例作⽤域)
request:请求作⽤域
session:会话作⽤域
application:全局作⽤域
websocket:HTTP WebSocket 作⽤域
后四种都是SpringMVC中限定使用的,因此现阶段我们只学前两个就行。
回到刚才的案例,Bean2希望获取到的bean对象是未被修改的,我们就可以将单例模式修改为多例模式。
使用@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
使用@Scope("prototype")
ps
prototype :
Portée du prototype (portée à instances multiples)
Les quatre derniers sont tous Son utilisation est limitée dans SpringMVC, donc à ce stade, nous n'avons besoin d'apprendre que les deux premiers.
Revenant au cas tout à l'heure, Bean2 espère que l'objet bean obtenu n'a pas été modifié, afin que nous puissions modifier le mode singleton en mode instance multiple.
Utilisez @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
Utiliser @Scope("prototype")
🎜🎜🎜🎜2. Processus d'exécution du Spring et cycle de vie du Bean🎜🎜🎜🎜ps</ code > : Lorsque l'exécution atteint l'étape d'assemblage des propriétés du Bean, lorsque l'injection d'attribut est analysée, l'injection de classe sera arrêtée en premier et l'injection d'attribut sera prioritaire, car l'attribut pourra être utilisé dans des méthodes ultérieures. 🎜🎜2.1 Cycle de vie du haricot🎜🎜Le soi-disant cycle de vie fait référence à l'ensemble du processus de vie d'un objet, de la naissance à la destruction. Nous appelons ce processus le cycle de vie d'un objet. 🎜🎜🎜Le cycle de vie d'un Bean est divisé en 5 parties suivantes : 🎜🎜🎜🎜🎜1. Instancier le Bean (allouer de l'espace mémoire au Bean) 🎜🎜🎜🎜2. Définir les propriétés (injection et assemblage du Bean) 🎜. 🎜🎜🎜3 .Bean initialization🎜🎜🎜🎜 implémente diverses méthodes de notification Aware, telles que les méthodes d'interface BeanNameAware, BeanFactoryAware et ApplicationContextAware. Par exemple : lorsque Spring initialise un bean, il doit attribuer un identifiant (nom) au bean. Si le beanName est défini avec succès, une notification beadNameAware sera générée ; exécutez la pré-méthode d'initialisation de BeanPostProcessor (si cette méthode n'est pas remplacée, suivez le code source, exécutez la méthode d'initialisation @PostConstruct, qui sera exécutée après l'injection de dépendance) ; opération ; exécute l'init spécifié par vous-même. La méthode -method (si spécifiée) est la méthode spécifiée dans la balise du bean au Spring 🎜🎜🎜🎜🎜Cette méthode d'initialisation et la méthode ci-dessus initialisée avec des annotations sont des produits de deux périodes Init différentes ; est un produit de l'ère XML. @PostConstruct est un produit de l'ère des annotations. Priorité : lorsque la méthode de M. Liang existe en même temps, l'annotation sera exécutée en premier, puis init sera exécuté pour exécuter la post-méthode d'initialisation de BeanPostProcessor (si cette méthode n'est pas remplacée, suivez le code source). 🎜🎜🎜🎜4. Utilisez Bean🎜🎜🎜🎜5. Destroy Bean pour détruire diverses méthodes du conteneur, telles que @PreDestroy, méthode d'interface DisposableBean, méthode de destruction. 🎜</li></ul><p>@PreDestroy和destroy-method的关系和初始化方法的两个关系差不多<br/>优先级:@ProDestroy > 重写的DisposableBean接口方法 > destroy-method</p><p><strong>执行流程图如下:</strong></p><p><img src="https://img.php.cn/upload/article/000/000/164/168311995723732.png" alt="Quelle est la portée et le cycle de vie de Bean dans Java Spring" /></p><p><code>ps:
实例化和初始化的区别:实例化
就是 分配内存空间。初始化
,就是把我们一些参数,方法的具体实现逻辑给加载进去。xml配置如下:
Bean
public class BeanLifeComponent implements BeanNameAware { @PostConstruct public void PostConstruct(){ System.out.println("执行@PostConstruct"); } public void init(){ System.out.println("执行bean-init-method"); } public void use(){ System.out.println("正在使用bean"); } @PreDestroy public void PreDestroy(){ System.out.println("执行@PreDestroy"); } public void setBeanName(String s){ System.out.println("执行了Aware通知"); } }
启动类
public class App2 { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); BeanLifeComponent beanLifeComponent = context.getBean(BeanLifeComponent.class); beanLifeComponent.use(); context.destroy(); } }
xml配置
<?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:content="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 https://www.springframework.org/schema/context/spring-context.xsd"> <content:component-scan base-package="com.beans"></content:component-scan> <bean id="1" class="com.beans.BeanLifeComponent" init-method="init"></bean> </beans>
@Controller public class TestUser { @Autowired private Test test; public TestUser(){ test.sayHi(); System.out.println("TestUser->调用构造方法"); } }
如果这段代码先执行了初始化,也就是其构造方法,会用到test对象,此时还没有设置属性,test就为null,会造成空指针异常。因此必须先设置属性,在进行初始化。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!