-
bean属性的继承
extend 父类
多个bean具有相同属性,但是没有继承关系,将配置文件class去掉
查看全部 -
bean属性的初始化和销毁
bean标签
实现接口
查看全部 -
构造ioc容器的约定
查看全部 -
通过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作用域)
查看全部 -
课程内容:ioc
查看全部 -
java web 发展2
查看全部 -
java web 发展
查看全部 -
懒加载lazy-init在被需要的时候才进行实例化的创建,仅对单例模式起作用,否则在spring上下文的进行初始化的时候进行实例的创建
查看全部 -
求ppt查看全部
-
通过xml注入Bean:
1、通过有参构造方法注入Bean
步骤1:创建Bean的类(包括创建AnotherBean,作为Bean的依赖属性),并提供有参的构造方法。
public class Bean {
private AnotherBean anotherBean;
private String string;
public Bean(AnotherBean anotherBean, String string) {
super();
this.anotherBean = anotherBean;
this.string = string;
}
}
步骤2:配置Spring.xml,通过<constructor-arg>标签注入Bean,该标签在<bean>标签里编写。
<constructor-arg>标签属性:
index——表示当前参数在构造方法中是第几个。
name——Bean的属性名。
type——表示参数的类型(如果为简单类型则写简单类型(java.lang.int),如果为依赖类型一般为类型的路径)。
value——适合简单的应用类型(int、String、float等)
ref——该Bean依赖另一Bean,它的值一般为被依赖Bean(AnotherBean)的<bean>的唯一标识Id。
代码:<bean id="anotherbeanId" class="main.java.com.Bean注入.构造器注入.AnotherBean"></bean>
<bean class="main.java.com.Bean注入.构造器注入.Bean" id="beanId">
<constructor-arg index="0" name="anotherBean" type="main.java.com.Bean注入.构造器注入.AnotherBean" ref="anotherbeanId"></constructor-arg>
<constructor-arg index="1" name="string" type="java.lang.String" value="哈哈"></constructor-arg>
</bean>
2、通过set方法注入Bean(注意:使用Set方法注入Bean,一定要提供无参构造函数)
步骤1:创建Bean的类(包括创建AnotherBean,作为Bean的属性),并提供get/set方法。
public class Bean {
private AnotherBean anotherBean1;
private String string1;
public AnotherBean getAnotherBean1() {
return anotherBean1;
}
public void setAnotherBean1(AnotherBean anotherBean1) {
this.anotherBean1 = anotherBean1;
}
public String getString1() {
return string1;
}
public void setString1(String string1) {
this.string1 = string1;
}
步骤2:配置Spirng.xml,通过<property>标签注入Bean,该标签在<bean>标签里。
<property>标签属性:
name——Bean的属性名
ref——该Bean依赖另一Bean,它的值一般为被依赖Bean(AnotherBean)的<bean>的唯一标识Id。
value——适合简单的应用类型(int、String、float等)
<bean id="anotherbeanId" class="main.java.com.Bean注入.构造器注入.AnotherBean"></bean>
<bean class="main.java.com.Bean注入.构造器注入.Bean" id="beanId">
<property name="anotherBean1" ref="anotherbeanId"></property>
<property name="string1" value="嘿嘿"></property>
</bean>
如果把Bean依赖的<bean>标签放在<property>里边则不会创建实例。
<bean class="main.java.com.Bean注入.构造器注入.Bean" id="beanId">
<property name="anotherBean1">
<bean id="" class="main.java.com.Bean注入.构造器注入.AnotherBean"></bean>
</property>
<property name="string1" value="嘿嘿"></property>
</bean>
注入Bean的简单写法:不需要<constructor-arg>和<property>标签。
步骤1:<beans>标签描述里添加两条描述——
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
代码:
<!-- c代表通过构造方法注入Bean,Constructor的首字母
c:_0中的0代表构造方法中第一个参数,c:_0-ref中的ref代表value和ref的区分
c:anotherBean中的anotherBean代表Bean属性名,c:anotherBean-ref中的ref代表ref和value的区分
p代表通过set方法注入Bean,property的首字母
<bean id="anotherbeanId" class="main.java.com.Bean注入.构造器注入.AnotherBean"></bean>
<bean class="main.java.com.Bean注入.构造器注入.Bean" id="beanId" c:anotherBean-ref="anotherbeanId" c:string="嘻嘻" p:anotherBean1-ref="anotherbeanId" p:string1="呵呵"></bean>
3、集合类型属性的Bean的注入(List、Set、Map、Properties,通过set方式注入)
步骤1:创建注入Bean的类(包括创建集合类型的属性、包括基本和依赖类型,作为Bean的属性)。
步骤2:配置spring.xml(通过set方式注入Bean)
<bean id="anotherbeanId" class="main.java.com.Bean注入.构造器注入.AnotherBean"></bean>
<bean class="main.java.com.Bean注入.构造器注入.Bean" id="beanId">
<property name="stringList">
<list>
<value>哈哈</value>
<value>嘿嘿</value>
</list>
</property>
<property name="anotherbeanList">
<list>
<ref bean="anotherbeanId"></ref>
<ref bean="anotherbeanId"></ref>
</list>
</property>
<property name="stringSet">
<set>
<value>哈哈</value>
<value>嘿嘿</value>
</set>
</property>
<property name="anotherbeanSet">
<set>
<ref bean="anotherbeanId"></ref>
<ref bean="anotherbeanId"></ref>
</set>
</property>
<property name="stringMap">
<map>
<entry key="aaa" value="张三"></entry>
<entry key="bbb" value="李四"></entry>
</map>
</property>
<property name="anotherbeanMap">
<map>
<entry key-ref="anotherbeanId" value-ref="anotherbeanId"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="ccc">王五</prop>
</props>
</property>
</bean>
测试:
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring-zhuru.xml");
Bean bean=context.getBean("beanId",Bean.class);
System.out.println(bean.getStringList());
System.out.println(bean.getAnotherbeanList());
System.out.println(bean.getStringSet());
System.out.println(bean.getAnotherbeanSet());
System.out.println(bean.getStringMap());
System.out.println(bean.getAnotherbeanMap());
System.out.println(bean.getProperties());
}
4、null值注入
步骤1:创建Bean的类(创建一个Bean的属性)。
public class Bean {
private AnotherBean anotherBean2;
public Bean(){
}
public AnotherBean getAnotherBean2() {
return anotherBean2;
}
public void setAnotherBean2(AnotherBean anotherBean2) {
this.anotherBean2 = anotherBean2;
}
}
步骤2:配置spring.xml。
<property name="anotherBean2">
<null></null>
</property>
测试:
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring-zhuru.xml");
Bean bean=context.getBean("beanId",Bean.class);
System.out.println(bean.getAnotherBean2());
}
5、注入时创建内部Bean
解释:<property>标签里可以不适用ref这个属性去使用<bean>的id,而是在<property>标签里使用如下在注入Bean时才去实例化该属性,并进行注入。
<property name="anotherBean1">
<bean class="main.java.com.Bean注入.构造器注入.AnotherBean"></bean>
</property>
查看全部 -
通过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管理Bean:
前提:导入相应包。
步骤:1、创建xml文件,并定义bean标签(id属性和class属性)。
2、通过ApplicationContext读取xml文件,获取spring上下文。
3.通过ApplicationContext对象的getBean方法获取Bean。
Spring.xml文件:
<bean id="bean的唯一标识" class="实例化bean的路径"/>
测试类Test:
public class TestBean {
@Test
public void test(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring-ioc.xml");
//第一个参数是xml中的唯一Id,第二个参数是返回的bean的类型。
Bean bean=context.getBean("bean",Bean.class);
System.out.println(bean);
}
}
查看全部 -
编写自己的IoC的约定: 简化IoC的业务逻辑,(对IOC容器的要求)。
所有Bean的生命周期交由IoC容器管理
所有被依赖的Bean通过构造方法执行注入(还可以通过set方式进行注入)
被依赖的Bean需要优先创建(例如张三依赖于奥迪,如果想要创建张三这个对象,则一定先创建奥迪这个对象)
使用Ioc的好处:1、所有依赖关系被统一管理。
2、每个类只需要管理自己的业务逻辑。
3、修改依赖关系变得容易。
IOC容器的编写:
/*
* 1、实例化bean(包括依赖对象和被依赖对象)
* 2、保存bean(要有一个私有域来保存创建好的bean,用Map集合来保存bean)
* 3、提供bean
* 4、每一个bean要产生一个Id与之相对应
*/
public class IocContainer {
//保存Bean——Id对应String类型,bean对应Object类型,考虑线程安全问题没用HashMap实现类。
private Map<String,Object> beans=new ConcurrentHashMap<String,Object>();
//提供Bean
public Object getBean(String beanId){
return beans.get(beanId);
}
/*实例化Bean——方法的参数:1、参数一:IOC要实例化的Bean来源哪个类(用到类的反射知识)
* 2、参数二:IOC要实例化的Bean的Id是什么
* 3、参数三:依赖奥迪的BeanId,通过方法参数告诉Ioc张三依赖于奥迪
*
*/
public void setBean(Class<?> clazz,String beanId,String...paramsBeanId){
//String类型的可变长度的数组:String...paramsBeanId
// 实现分为3步:1、因为通过构造方法创建bean,所以组装构造方法所需要的参数值
Object [] paramsValue=new Object[paramsBeanId.length];
for(int i=0;i<paramsBeanId.length;i++){
//将方法传过来的依赖的属性Bean的Id通过集合beans获取该对象(可以多个)的实例
paramsValue[i]=beans.get(paramsBeanId[i]);
}
// 2、调用构造方法实例化bean
// clazz.getConstructors(),拿到该bean的所有构造方法
Object bean=null;
for (Constructor<?> constructor : clazz.getConstructors()) {
try {
bean=constructor.newInstance(paramsValue);
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
} catch (InvocationTargetException e) {
}/*所有的异常都不处理:如果这个bean有多个构造方法,
那么至少有一个构造方法能通过这些参数值完成实例化。
*/
}
if(bean==null){//一个构造方法都没能通过的情况
throw new RuntimeException("找不到合适的构造方法去实例化Bean");
}
// 3、将实例化的bean放入集合beans
beans.put(beanId, bean);
}
}
测试类的编写:
public class TestIocContainer {
private IocContainer iocContainer=new IocContainer();
@Before
//创建Bean和使用Bean是两个不同的业务逻辑
public void before(){
iocContainer.setBean(AoDi.class,"aodi");
iocContainer.setBean(BieKe.class,"bieke");
iocContainer.setBean(ZhangSan.class,"zhangsan","aodi");
iocContainer.setBean(LiSi.class,"lisi","bieke");
}
@Test
public void test(){
Humen zhangsan=(Humen) iocContainer.getBean("zhangsan");
zhangsan.goHome();
Humen lisi=(Humen) iocContainer.getBean("lisi");
lisi.goHome();
}
}
查看全部 -
IoC概念:Inversion of Control控制反转,控制:控制JavaBean对象的创建及销毁(生命周期),反转:将对象的控制权交给IoC容器(在如果对象之间有依赖关系,使用依赖对象时则要创建被依赖对象,被依赖对象的控制权在依赖对象手里,使用IoC则把控制权交给容器手里)。
控制反转和依赖注入:是两个不同的概念,但确实相辅相成的两个概念,是解释ioc两个不同的角度。
耦合性:1、把声明对象放在类的属性域里,降低了耦合性,减少了对象的重复创建和销毁。
符合类型设计的规范:一般对属性通过构造方法传入,或者是set方法传入。(抽象的想,一个类自己不创建对象)
个人理解:控制反转——》被依赖对象的创建交给IOC容器负责,当使用依赖对象时,IOC创建被依赖对象。
依赖注入——》被依赖对象创建完成后,通过构造器注入或者是set方法方式注入对依赖对象进行 赋值。
查看全部 -
Java Web发展史: 第一阶段:JavaBean+Servlet+Jsp逐步发展 第二阶段:面对EJB重量级框架带来的种种麻烦 第三阶段:SpringMVC/Struts+Spring+Hibernate/myBatis 第四阶段:享受SpringBoot"约定大于配置"的种种乐趣,很多繁琐的配置都变成了约定 第五阶段:以Dubbo为代表的SOA为服务架构体系(Dubbo是阿里创建的) 第六阶段:比较前沿的技术,SpringCloud微服务架构技术生态圈(基于SpringBoot,保证了开箱即用,需要什么SpringCloud保证都有)
查看全部
举报