-
Bean的懒加载
测试:
@Test
public void test(){
ApplicationContext ac=new ClassPathXmlApplicationContext("spring_lanjiazai.xml");
System.out.println("context被创建了");
Bean bean=ac.getBean("bean", Bean.class);
System.out.println(bean);
结果:
Bean被创建了
context被创建了
main.java.com.Bean懒加载.Bean@b8a1063
证明:当Spring上下文初始化时,作用域为singleton的Bean就已经被创建好了,而不是通过Spring上下文获取时才去创建。
Bean懒加载概念:
Spring容器会在创建容器时提前初始化Singleton作用域的bean,但是如果Bean被标注了lazy-init=“true”,则该Bean只有在其被需要的时候才会被初始化。(只对singleton作用域的bean有效)
代码:
<bean id="bean" class="main.java.com.Bean懒加载.Bean" scope="singleton" lazy-init="true"></bean>
解决多个bean使用懒加载问题:
<beans标签里添加default-lazy-init=“true”>:表示spring配置文件里所有bean都是懒加载模式。
使用场景:
如果某个Bean在程序整个运行周期都可能不会被使用,那么可考虑设定该Bean为懒加载。
优点:尽可能的节省了资源。
缺点:可能会导致某个操作相应操作时间增加。
查看全部 -
这节课内容如下 1 通过注解减少配置 @configuration 相当于spring.xml整个xml的配置 @bean 相当于bean标签 另外可以让spring自动扫描注解,配置@componentScan,效果同component-scan标签 类似@component可以被管理的标签有@controller,@service,@repository 等 2 bean的别名配置 @bean的value可以配一个数组查看全部
-
把一个java bean交给spring管理步骤:
1、创建一个xml格式的配置文件
2、在xml文件中定义一个bean,给每个bean设定一个id
3、通过ApplicationContext获取Spring上下文
ApplicationContext context = new ClassPathXmlApplicatioinContext("文件名.xml");
4、获取bean
Bean bean = context.getBeal("第一步中给bean的id",Bean.class);
查看全部 -
通过注解开启Bean的懒加载
懒加载:创建spring上下文时,并不会实例化Bean,而是在获取Bean时,才去实例化Bean。
步骤1:创建配置扫描文件,并添加注解@Configuration,@ComponentScan(“路径”),这种在@Component下添加注解@Lazy,也可以不添加扫描注解,可以提供一个返回Bean实例的方法,并在方法上添加@Bean注解,通过这种实现懒加载,则在@Bean下添加注解@Lazy。
@Configuration
@ComponentScan("springlazy")
public class Configuration1 {
@Bean(name="bean2")
@Lazy
public Bean1 bean(){
return new Bean1();
}
}
步骤2:Bean类代码。
@Component(value="bean1")
@Lazy
public class Bean1 {
public Bean1(){
System.out.println("Bean1被创建了");
}
}
xml在<beans>标签里添加default-lazy-init通过注解实现。
@Configuration注解下添加@Lazy注解:该容器中所有作用域为singleton的Bean对象都会被懒加载。
代码:
@Configuration
@ComponentScan("springlazy")
@Lazy
public class Configuration1 {
@Bean(name="bean2")
public Bean1 bean(){
return new Bean1();
}
}
查看全部 -
Spring通过注解注入Bean
@Autowired:通过该注解实现构造方法注入和set方法注入,可以标识在有参构造方法上、set方法上、属性上。
一、通过方法注入Bean
1:通过有参构造方法注入
步骤1:创建扫描配置类,并添加注解@Configuration、@ComponentScan(value=“路径”)
代码:
@Configuration
@ComponentScan(value="springzhuru")
public class MyConfiguration {
}
步骤2:创建要实例化的Bean,并提供有参的构造方法,并在构造方法上添加注解@Autowired在类上添加@Component。
代码:@Component
public class MyBean {
private AnotherBean anotherBean;
@Autowired
public MyBean(AnotherBean anotherBean) {
super();
this.anotherBean = anotherBean;
}
测试代码:
@Test
public void test(){
ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfiguration.class);
MyBean bean1=ac.getBean("myBean",MyBean.class);
System.out.println(bean1);
}
结果:
MyBean [anotherBean=springzhuru.AnotherBean@27b47740]
2:通过set方法注入
步骤1:创建扫描配置类,并添加注解@Configuration、@ComponentScan(value=“路径”)
代码:
@Configuration
@ComponentScan(value="springzhuru")
public class MyConfiguration {
}
步骤2:创建要实例化的Bean,并提供set方法,并在set方法上添加注解@Autowired在类上添加@Component。
@Component(value="myBean")
public class MyBean {
private AnotherBean anotherBean;
private AnotherBean anotherBean1;
@Autowired
public MyBean(AnotherBean anotherBean) {
super();
System.out.println("MyBean被创建了");
this.anotherBean = anotherBean;
}
@Autowired
public void setAnotherBean1(AnotherBean anotherBean1) {
this.anotherBean1 = anotherBean1;
}
@Override
public String toString() {
return "MyBean [anotherBean=" + anotherBean + ", anotherBean1=" + anotherBean1 + "]";
}
}
测试:
@Test
public void test(){
ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfiguration.class);
MyBean bean1=ac.getBean("myBean",MyBean.class);
System.out.println(bean1);
}
结果:anotherBean和anotherBean1相等,@Component是默认单例模式,同一spring上下文中只会创建一个AnotherBean的对象。
MyBean [anotherBean=springzhuru.AnotherBean@3c8587f, anotherBean1=springzhuru.AnotherBean@3c8587f]
二、集合类型Bean的注入
1、List集合类型Bean的注入
步骤1:创建注入Bean的类(包括创建集合类型的属性,基本类型的作为Bean的属性),并提供set方法,添加@Resource注解。
public class MyBean {
private List<String> stringList;
public List<String> getStringList() {
return stringList;
}
@Resource //@Resource注解首先会根据属性名称注入,其次会根据类型进行注入。
public void setStringList(List<String> stringList) {
this.stringList = stringList;
}
}
步骤2:扫描配置类,提供List<String>类型的实例的方法,并添加@Bean注解,告知spring由spring管理的方法。
@Bean
public List<String> stringList(){
List<String> list=new ArrayList<String>();
list.add("哈哈");
list.add("嘿嘿");
list.add("呵呵");
return list;
}
测试:
@Test
public void test(){
ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfiguration.class);
MyBean myBean=ac.getBean("myBean",MyBean.class);
System.out.println(myBean);
for (String s:myBean.getStringList()) {
System.out.println(s);
}
}
通过注解注入List的第二种方式:在扫描配置类中添加几个返回类型为字符串类型的方法,返回的字符串都会被注入到Bean的集合属性中。
@Configuration
@ComponentScan(value="springzhuru")
public class MyConfiguration {
@Bean
public String string1(){
return "111";
}
@Bean
public String string2(){
return "222";
}
}
测试:
MyBean [anotherBean=springzhuru.AnotherBean@7ea7476f, anotherBean1=springzhuru.AnotherBean@7ea7476f, anotherBean2=springzhuru.AnotherBean@7ea7476f, stringList=[222, 111]]
222
111
List注入方式:如果一个Bean有一个List类型的属性需要注入,spring会到上下文中(扫描注解类)查找所有该List中定义泛型的所有实例(带有@Bean),然后将所有实例注入到List里面。
@Qualifier("stringList")指定Id,而且在集合属性的set方法上的@Qualifier(“stringList”)指定Id。
拓展:@Order(数值),来控制实例化Bean的顺序,小的先注入。前提:Spring4.2版本以后该注解才起作用,可以通过它实现注入集合中数据的顺序。
Map注入
步骤1:创建Map类型的集合,并提供set方法
public class MyBean {
private Map<String,Integer> getIntegerMap;
@Resource("map")
public void setGetIntegerMap(Map<String, Integer> getIntegerMap) {
this.getIntegerMap = getIntegerMap;
}
public Map<String, Integer> getGetIntegerMap() {
return getIntegerMap;
}
}
步骤2:扫描配置文件中提供返回map集合的方法。@Bean("map")
public Map<String,Integer> integerMap(){
Map<String,Integer> map=new HashMap<String,Integer>();
map.put("aaa", 111);
map.put("bbb", 222);
map.put("ccc", 333);
return map;
}
测试:
@Test
public void test(){
ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfiguration.class);
MyBean myBean=ac.getBean("myBean",MyBean.class);
System.out.println(myBean);
for(Entry<String,Integer> entry:myBean.getGetIntegerMap().entrySet()){
System.out.println(entry);
}
}
Map注入的第二种方式:同List相同,创建多个方法返回Integer类型参数。
扫描配置类代码:@Bean //该情况下key的值为Bean的名
public Integer integerMap1(){
return 444;
}
@Bean
public Integer integerMap2(){
return 555;
}
结果:还可以通过给@Bean(name="名称")来给实例取名。
springzhuru.MyBean@11de0733
integerMap1=444
integerMap2=555
四、String、Integer等简单类型的注入
步骤1:创建简单数据类型的变量,并提供set方法,并在set方法上添加
@value(“值”)注解。
public class MyBean {
private String string;
public String getString() {
return string;
}
@Value("2222")
public void setString(String string) {
this.string = string;
}
}
测试:
@Test
public void test(){
ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfiguration.class);
MyBean myBean=ac.getBean("myBean",MyBean.class);
System.out.println(myBean);
}
结果:MyBean [string=2222]
五、SpringIoC容器内置接口实例注入
private ApplicationContext context;
//这种情况下,可以直接使用ApplicationContext方法
public ApplicationContext getContext() {
return context;
}
@Autowired
public void setContext(ApplicationContext context) {
this.context = context;
}
拓展:除了可以将ApplicationContext注入进来,还可以将BeanFactory、Environment、ResourceLoader、ApplicationEventPublisher、MessageResource及其实现类。
查看全部 -
通过Spring的xml文件配置Bean作用域:(Spring默认作用域是Singleton)
1、Singleton作用域(单例模式:通过Spring容器实现单例模式,具有局限性:保证在一个Spring上下文(ApplicationContext)是单例模式,多个AppliactionContext单例模式就失效了。
定义:如果一个<bean>的作用域为Singleton,则该<bean>只会被实例化一次,只有一个Bean会被创建。(每次向Spring上下文(ApplicationContext生命周期存活)请求这个实例时,Spring都会返回同一个实例)。
代码:
public class Bean1 {
private Bean2 bean2;
public Bean1(){
}
public Bean2 getBean2() {
return bean2;
}
public void setBean2(Bean2 bean2) {
this.bean2 = bean2;
}
}
public class Bean2 {
}
<bean id="bean2" class="main.java.com.Bean作用域.Singleton.Bean2" scope="singleton"></bean>
<bean id="bean1" class="main.java.com.Bean作用域.Singleton.Bean1">
<property name="bean2" ref="bean2"></property>
</bean>
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring-singleton.xml");
Bean2 bean2_1=context.getBean("bean2", Bean2.class);
System.out.println(bean2_1);
Bean2 bean2_2=context.getBean("bean2", Bean2.class);
System.out.println(bean2_2);
Bean1 bean1=context.getBean("bean1",Bean1.class);
System.out.println(bean1);
}
测试结果:
main.java.com.Bean作用域.Singleton.Bean2@a690707
main.java.com.Bean作用域.Singleton.Bean2@a690707
Bean1 [bean2=main.java.com.Bean作用域.Singleton.Bean2@a690707]
2、prototype作用域(多例模式)
定义:如果一个<bean>的作用域为prototype,则该<bean>会被实例化多次,有多个Bean会被创建(每次向Spring上下文请求该Bean都会new一个新的实例)。
代码:
public class Bean1 {
private Bean2 bean2;
public Bean1(){
}
public Bean2 getBean2() {
return bean2;
}
public void setBean2(Bean2 bean2) {
this.bean2 = bean2;
}
}
public class Bean2 {
}
<bean id="bean2" class="main.java.com.Bean作用域.Singleton.Bean2" scope="prototype"></bean>
<bean id="bean1" class="main.java.com.Bean作用域.Singleton.Bean1">
<property name="bean2" ref="bean2"></property>
</bean>
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring-singleton.xml");
Bean2 bean2_1=context.getBean("bean2", Bean2.class);
System.out.println(bean2_1);
Bean2 bean2_2=context.getBean("bean2", Bean2.class);
System.out.println(bean2_2);
Bean1 bean1=context.getBean("bean1",Bean1.class);
System.out.println(bean1);
}
测试结果:
main.java.com.Bean作用域.Singleton.Bean2@34dfdf92
main.java.com.Bean作用域.Singleton.Bean2@55cf055c
Bean1 [bean2=main.java.com.Bean作用域.Singleton.Bean2@a690707]
拓展:bean1和bean2分别设置单例模式和多例模式进行不同组合使用。
1:bean1和bean2都是单例模式,则bean1的实例相等,bean1的属性bean2相等。
代码:
<bean id="bean2" class="main.java.com.Bean作用域.Singleton.Bean2" scope="singleton"></bean>
<bean id="bean1" class="main.java.com.Bean作用域.Singleton.Bean1" scope="singleton">
<property name="bean2" ref="bean2"></property>
</bean>
Bean1 bean1_1=context.getBean("bean1",Bean1.class);
System.out.println(bean1_1);
Bean1 bean1_2=context.getBean("bean1",Bean1.class);
System.out.println(bean1_2);
System.out.println(bean1_1==bean1_2);
结果:
Bean1 [bean2=main.java.com.Bean作用域.Singleton.Bean2@34dfdf92]
Bean1 [bean2=main.java.com.Bean作用域.Singleton.Bean2@34dfdf92]
true
2:bean1是单例模式和bean2都是多例模式,则bean1的实例相等,bean1的属性bean2也相等(因为bean1是单例模式,Spring只实例化一次bean1,bean2只需要被实例化一次)。
代码:
<bean id="bean2" class="main.java.com.Bean作用域.Singleton.Bean2" scope="prototype"></bean>
<bean id="bean1" class="main.java.com.Bean作用域.Singleton.Bean1" scope="singleton">
<property name="bean2" ref="bean2"></property>
</bean>
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring-singleton.xml");
Bean1 bean1_1=context.getBean("bean1",Bean1.class);
System.out.println(bean1_1);
Bean1 bean1_2=context.getBean("bean1",Bean1.class);
System.out.println(bean1_2);
System.out.println(bean1_1==bean1_2);
}
Bean1 [bean2=main.java.com.Bean作用域.Singleton.Bean2@55cf055c]
Bean1 [bean2=main.java.com.Bean作用域.Singleton.Bean2@55cf055c]
true
3:bean1是多例模式和bean2都单例模式,则bean1的实例不相等,bean1的属性bean2相等
代码:
<bean id="bean2" class="main.java.com.Bean作用域.Singleton.Bean2" scope="singleton"></bean>
<bean id="bean1" class="main.java.com.Bean作用域.Singleton.Bean1" scope="prototype">
<property name="bean2" ref="bean2"></property>
</bean>
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring-singleton.xml");
Bean1 bean1_1=context.getBean("bean1",Bean1.class);
System.out.println(bean1_1);
Bean1 bean1_2=context.getBean("bean1",Bean1.class);
System.out.println(bean1_2);
System.out.println(bean1_1==bean1_2);
}
Bean1 [bean2=main.java.com.Bean作用域.Singleton.Bean2@a690707]
Bean1 [bean2=main.java.com.Bean作用域.Singleton.Bean2@a690707]
false
4:bean1是多例模式和bean2都多例模式,则bean1的实例不相等,bean1的属性bean2不相等
<bean id="bean2" class="main.java.com.Bean作用域.Singleton.Bean2" scope="prototype"></bean>
<bean id="bean1" class="main.java.com.Bean作用域.Singleton.Bean1" scope="prototype">
<property name="bean2" ref="bean2"></property>
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring-singleton.xml");
Bean1 bean1_1=context.getBean("bean1",Bean1.class);
System.out.println(bean1_1);
Bean1 bean1_2=context.getBean("bean1",Bean1.class);
System.out.println(bean1_2);
System.out.println(bean1_1==bean1_2);
}
Bean1 [bean2=main.java.com.Bean作用域.Singleton.Bean2@66e376e1]
Bean1 [bean2=main.java.com.Bean作用域.Singleton.Bean2@5f91e28c]
false
方法注入:声明一个protected、抽象、返回值为被依赖Bean类型的方法。(protected abstract Bean2 createBean2();)
适用于如下场景——
bean1是Singleton,bean2是Prototype,Bean1依赖Bean2,每次获得Bean1的时候,正常情况下Bean2是相同的,方法注入则使Bean2不同。
代码:
public abstract class Bean1 {
public abstract Bean2 createBean2();
public void printBean2(){
System.out.println(createBean2());
}
public Bean1(){
}
}
<bean id="bean2" class="main.java.com.Bean作用域.Singleton.Bean2" scope="prototype"></bean>
<bean id="bean1" class="main.java.com.Bean作用域.Singleton.Bean1" scope="singleton">
<lookup-method name="createBean2" bean="bean2"/>
</bean>
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring-singleton.xml");
Bean1 bean1_1=context.getBean("bean1",Bean1.class);
System.out.println(bean1_1.createBean2());
System.out.println(bean1_1.createBean2());
System.out.println(bean1_1.createBean2());
}
测试结果:
main.java.com.Bean作用域.Singleton.Bean2@2467149d
main.java.com.Bean作用域.Singleton.Bean2@6b7a6216
main.java.com.Bean作用域.Singleton.Bean2@2fbdc97a
3、Web环境作用域(request作用域、session作用域、application作用域、websocket作用域)
4、自定义作用域(Spring内置的自定义SimpleThreadScope作用域)
查看全部 -
通过Spring的xml文件实现Bean:(注意:只要Spring.xml中配置了bean标签,则就会根据class创建这个bean的实例)
1、通过构造方法实例化Bean。
步骤1:创建要实例化的类,并提供无参构造方法。
public class Bean {
public Bean(){
System.out.println("Bean被创建了");
}
步骤2:spring.xml中配置
<bean id="bean的唯一标识" class="要实例化bean的路径"></bean>
测试:ApplicationContext context=new ClassPathXmlApplicationContext(spring.xml的路径);
Bean bean=context.getBean("bean",Bean.class);
System.out.println(bean);
2、通过静态方法实例化Bean。(通过Bean2的工厂的静态方法实例化Bean)
步骤1:创建Bean2的工厂Bean2Factory类以及Bean2类,并且提供一个静态、返回值类型为Bean2的方法,返回new Bean2()。
public class Bean2Factory {
public static Bean2 getBean2(){
return new Bean2();
}
}
public class Bean2 {
public Bean2(){
System.out.println("Bean2被创建了。");
}
步骤2:配置Spring.xml
<bean class="Bean2工厂的路径" factory-method="Bean2工厂的静态方法名" id="Bean2工厂的唯一标识"></bean>
测试:
ApplicationContext context=new ClassPathXmlApplicationContext("spring-ioc2.xml");
Bean2 bean=context.getBean("bean2factoryId",Bean2.class);
System.out.println(bean);
3、通过实例方法实例化Bean。(通过Bean2的工厂的实例方法实例化Bean)
步骤1:创建Bean3的工厂Bean3Factory类以及Bean3类,并且提供一个返回值类型为Bean3的方法,方法返回new Bean3()。
public class Bean3Factory {
public Bean3 getBean3(){
return new Bean3();
}
}
public class Bean3 {
public Bean3(){
System.out.println("Bean3被创建了。");
}
}
步骤2:配置Spring.xml
<bean class="main.java.com.imooc2.Bean3Factory" id="bean3Factory"></bean>
<bean class="main.java.com.imooc2.Bean3" factory-bean="bean3Factory" factory-method="getBean3" id="bean3"></bean>
给bean取别名:有类Bean1,并且通过bean标签实例化Bean1,给Bean1的实例取多个名字。
例如:方式一:bean标签里添加name属性
<bean id="bean" class="main.java.com.imooc1.Bean" name="bean1_1,bean1_2"></bean>
方式二:添加<alias>标签
<bean id="bean" class="main.java.com.imooc2.Bean1" name="bean1_1,bean1_2"></bean>
<alias name="bean" alias="bean1_3"/><!-- alias只支持一个别名 -->
查看全部 -
Spring
查看全部 -
把一个Java bean交由spring来管理,分三个步骤:
创建一个xml配置文件。
将一个Bean交由Spring创建并管理。
获取Spring上下文,然后通过上下文获取Bean
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean class="com.imooc.spring.ioc.class.Bean1" id="bean1"/> </beans>
查看全部 -
IOC(不只是Spring的ioc,其他的框架也具有相同的IOC思想及应用):
控制: 控制对象的创建及销毁(生命周期)
反转:将对象的控制权交给IOC容器
查看全部 -
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
查看全部 -
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
查看全部 -
<servlet>
<servlet-name>SpringServlet</servlet-name>
<servlet-class>org.springframwork.web.servlet.DispatcherServlet</servlet-class>
<init-parm>
<parm-name>contextConfigLocation</parm-name>
<parm-value>classpath:spring.xml</parm-value>
</init-parm>
</servlet>
<servlet-mapping>
<servlet-name>SpringServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
查看全部 -
bean的继承在spring中的配置方式 可配置parent属性, 就算没有父类,也可以配置一个abstract 的bean,让其他bean设置parent,以配置相同属性查看全部
-
懒加载适用场景
查看全部
举报