Spring框架

Spring

JavaBean

符合一定规范的(结构雷同)简单Java对象

  1. 必须有包(package)
  2. 必须有无参数构造器
    • 方便子类的继承和创建
    • 方便利用无参数构造器创建对象
  3. 实现序列化接口
    • 方便底层自动调用对象的序列化功能
  4. 属性有get和set访问方法
    • get set 方法声明的属性称为“Bean属性”
    • 类中声明的实例变量称为“对象属性”

符合上述规范类,创建的具体对象称为JavaBean, 也称为简单Java对象,有时候也称为POJO对象。
Spring建议,在Spring中使用JavaBean规范的对象。 但是Spring也支持不规范的Java对象。
如上规范不是语法规范,可以不严格遵守。但是大多数企业都要求执行上述规范。

Spring核心功能IOC/DI

1. IOC控制反转: 指对象的创建和控制权利由Spring控制,用户程序只从Spring获取使用对象。 用户程序不再负责创建管理对象。Spring 内部提供了一个JavaBean对象容器(集合)由于创建和管理对象。
2. DI依赖注入: 指在需要对象时候,由当前环境创建管理对象,并且注入到使用者手中。

使用Spring:导入Spring框架API

<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.3.10.RELEASE</version>
		</dependency>
	
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
		</dependency>

Spring装配Bean的方式:

  1. 自动化装配
  2. 通过Java代码装配
  3. 通过XML文件装配

自动化装配

  • 组件扫描:Spring会自动发现应用上下文中所创建的bean
  • 自动装配:Spring自动满足bean之间的依赖
  1. 创建一个JavaBean类
/** 符合Java Bean 规范 */
public class HelloWorld implements Serializable {
	private String message = "Hello World";
	public HelloWorld() {
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	@Override
	public String toString() {
		return "HelloWorld [message=" + message + "]";
	}
}
  1. 添加@Component注解,告知Spring要为这个类创建Bean

可用@Component( “名字”)给Bean命名
或者使用@Named( “名字”)代替

  1. 默认情况下,组件扫描不开启,需要显式地配置组件扫描
@Configuration
@ComponentScan
public class BeanConfig {
	//...
}

@ComponentScan默认会扫描与配置类相同的包
也可用@ComponentScan(" 包名 “)、@ComponentScan(” basePackages=包名 “)
@ComponentScan(” basePackages={包名包名} “)
@ComponentScan(” basePackageClasses={类名类名} ")
使用类名更加安全

通过Java代码配置

@Comfiguration注解表明这是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节

@Bean注解会告诉Spring这个方法会返回一个对象,要注册为Spring应用上下文中的Bean

@Configuration
public class CDPlayerConfig {
  
  @Bean
  public CompactDisc compactDisc() {
    return new SgtPeppers();
  }
  
  @Bean
  public CDPlayer cdPlayer(CompactDisc compactDisc) {
    return new CDPlayer(compactDisc);
  }

}

通过XML文件配置

  1. 创建一个XML文件,告诉Spring创建哪些对象
	<?xml version="1.0" encoding="UTF-8"?>
	<beans 
		<!-- 省略了配置规范文件的导入-->
		<!-- 利用配置文件,告诉Spring管理哪些JavaBean对象 -->
		<bean id="hello" class="demo.HelloWorld"/>	
	</beans>
  1. 启动Spring容器,Spring会根据XML文件创建对象。
		ClassPathXmlApplicationContext ctx;
		@Before //在测试案例之前执行
		public void initCtx() {
			//初始化Spring容器, 需要提供配置文件
			//配置文件默认位置为 resources
			ctx =new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		}
		@After //在测试案例之后执行
		public void destroy() {
			ctx.close(); //关闭Spring容器,会销毁Bean对象
		}
  1. 从Spring获得创建好对象。
		@Test
		public void testHelloWorld() {
			//Spring中就已经创建了 HelloWorld对象,利用
			//ID获取Spring中创建的对象
			HelloWorld obj=(HelloWorld)ctx.getBean("hello");
			//检查是否成功创建了对象
			System.out.println(obj); 
		}

Spring常用的三种注入方式

  1. 构造方法注入
  2. setter方法注入
  3. 注解注入

详情见此文

Spring 容器

Spring 核心功能是管理JavaBean对象,由于其内部缓存了JavaBean对象,所以形象称为Spring为 JavaBean 容器。

  1. Spring为 JavaBean 容器。
  2. 由于Spring可以创建JavaBean对象,所以称为BeanFactory(JavaBean的工厂)
  3. 后来Spring在BeanFactory基础上扩展了接口 ApplicationContext。
    • 一般常用是 ApplicationContext
    • Application 应用,Context 上下文环境
    • 实际常用实现类是 ClassPathXmlApplicationContext
    • ClassPathXmlApplicationContext 是Spring容器、Bean容器也是Bean工厂

Spring 容器功能使用

  1. Spring 配置文件用于声明JavaBean对象

    <bean id="obj1" class="demo.HelloWorld"/>
    
  2. Spring配置文件中 id 属性和name属性功能一样

    <!-- id 属性和 name属性作用一样 -->
    <bean name="obj2" class="demo.HelloWorld"/>
    

    常用的属性是id

  3. Spring容器提供了多个获取Bean对象的方法:

    //返回是Object类型需要进行类型转换
    Object bean = ctx.getBean("BeanID")
    
    //返回具体类型的Bean对象		
    类型 obj = ctx.getBean("BeanID", 类型)
    

案例:

	<!-- 利用配置文件,告诉Spring管理哪些JavaBean对象 -->
	<bean id="obj1" class="demo.HelloWorld"/>
	<!-- id 属性和 name属性作用一样 -->
	<bean name="obj2" class="demo.HelloWorld"/>
	@Test
	public void testName() {
		//利用name属性获取Spring容器中的对象
		HelloWorld obj=(HelloWorld)ctx.getBean("obj2");
		//检查是否成功创建了对象
		System.out.println(obj); 
	}
	
	@Test
	public void testGetBean() {
		//Spring容器提供了多个获取Bean对象的方法:
		HelloWorld bean1 =  (HelloWorld)ctx.getBean("obj1");
		System.out.println(bean1);
		//返回具体类型的方法,无需类型转换(常用)
		HelloWorld bean2 = 
				ctx.getBean("obj1", HelloWorld.class);
		System.out.println(bean2); 
	}

Spring 创建对象的方式

  1. 利用无参数构造器创建对象
    1. 默认情况下,Spring会自动调用(反射调用)无参数构造器创建对象。
  2. 利用静态工厂方法创建对象, Spring可以利用工厂方法来创建对象
    1. “工厂方法” 创建对象方法称为工厂方法
	//配置文件:
	<!-- Spring利用静态工厂方法创建对象 -->
	<bean id="cal1" class="java.util.Calendar"
		factory-method="getInstance"/> 
		//测试案例:
		@Test 
		public void testCalendar() {
			//静态方法getInstance(),来创建Calendar对象
			//创建对象的静态方法称为,静态工厂方法。
			//Calendar cal = Calendar.getInstance();
		
			//Spring支持静态工厂方法创建对象
			//Spring可以去调用静态工厂方法,将创建的对象
			//放到Spring容器管理起来,提供给外部使用。
			
			Calendar cal1 =  ctx.getBean("cal1", Calendar.class);
			System.out.println(cal1); 
		}
  1. 利用对象工厂方法创建对象
    • 利用对象提供的工厂方法创建另外一个对象

	@Test
	public void testFactoryBean() {
		//测试利用Spring调用Bean对象的工厂方法创建对象
		Date date = ctx.getBean("date1", Date.class);
		System.out.println(date); 
	}

Spring 功能强大,提供了多种创建对象的方式。

单例与多例

单例的特点:

  1. 资源占用少, 一个对象可以被复用。
  2. 并发访问时候,单例对象的属性可能出现并发访问问题。

多个实例:

  1. 每个实例都有一组数据,资源占用高,可以保持多个状态
  2. 如果每个线程访问一个实例,就没有线程并发安全问题

Spring默认情况下按照单例管理对象!

案例:

	<!-- scope="prototype" 属性设置以后,obj3 
	是多例的,每次getBean都会创建一个新对象-->
	<bean id="obj3" class="day01.HelloWorld" 
		scope="prototype"/>
	@Test
	public void testPrototype() {
		//默认情况下Spring管理的对象是单例的
		HelloWorld obj1 = ctx.getBean("obj1",
				HelloWorld.class);
		HelloWorld obj2 = ctx.getBean("obj1",
				HelloWorld.class);
		System.out.println(obj1==obj2);
		//设置了 scope=prototype 属性返回是多例的
		HelloWorld obj3 = ctx.getBean("obj3",
				HelloWorld.class);
		HelloWorld obj4 = ctx.getBean("obj3",
				HelloWorld.class);
		System.out.println(obj3==obj4); 
	}

对象的生命周期管理

Spring支持对象的生命周期管理方法。

生命周期管理方法用于初始化,或者回收资源。

  1. 默认情况下是单例对象,Spring利用属性调用初始化和销毁方法
		<!-- 测试对象生命周期管理方法 -->
		<bean id="demo"	class="day01.DemoBean"
			init-method="init" destroy-method="destroy"/>

关闭容器时候调用 销毁方法。
容器启动时候创建对象调用其初始化方法

  1. 多例对象时候,Spring只在创建对象时候调用init方法。 不会调用销毁方法
		<!-- 测试对象生命周期管理方法 -->
		<bean id="demo"	class="day01.DemoBean"
			scopt="prototype"
			init-method="init" destroy-method="destroy"/>

getBean时候,创建对象并且调用init方法
如果需要执行销毁方法,只能手动执行

案例:

	public class DemoBean implements Serializable{
		private PrintWriter out;
		
		public void init() {
			//初始化资源
			try {
				out = new PrintWriter("demo.txt");
				System.out.println("打开文件 demo.txt"); 
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}
		public void destroy() {
			//关闭资源
			out.flush();
			out.close();
			System.out.println("文件被关闭了"); 
		}
		public void print(String str) {
			out.println(str); 
		}
	}

	public class DemoBean2 implements Serializable{
		private PrintWriter out;
		
		public void init() {
			//初始化资源
			try {
				out = new PrintWriter("demo2.txt");
				System.out.println("打开文件 demo2.txt"); 
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}
		public void destroy() {
			//关闭资源
			out.flush();
			out.close();
			System.out.println("文件被关闭了"); 
		}
		public void print(String str) {
			out.println(str); 
		}
	}
	<!-- 测试对象生命周期管理方法 -->
	<bean id="demo"	class="day01.DemoBean"
		init-method="init" destroy-method="destroy"/>

	<!-- 测试多例对象的生命周期管理方法  
	  destroy-method 写上没有意义,不会被执行-->
	<bean id="demo2" class="day01.DemoBean2"
		scope="prototype"
		init-method="init"/>
	@Test
	public void testLifecircle() {
		//测试Spring的Bean对象的生命周期管理功能
		DemoBean bean = ctx.getBean("demo",
				DemoBean.class);
		bean.print("abc"); 
	}
	
	@Test
	public void testPrototypeLifecircle() {
		//测试Spring多例Bean对象的生命周期管理功能
		DemoBean2 bean = ctx.getBean("demo2",
				DemoBean2.class);
		bean.print("abc");
		//手工调用销毁方法
		bean.destroy();
	}

懒惰实例化JavaBean

lazy: 懒惰,按需实例化

lazy-init=“true”: 在第一次请求getBean时候实例化对象。

  1. 默认情况下Spring对于单例对象,容器启动时候立即实例化。优点是在使用对象时候,对象已经实例化,可以减少延迟,提高性能。 会占用系统资源。
  2. lazy-init=“true” 属性,以后按需实例化,资源占用低,获取对象慢。
  3. 对于一定使用的对象,建议采用立即实例化规则
  4. 对于使用少的对象建议采用懒惰实例化
  5. Spring默认规则是 立即实例化

案例:

	<!-- 测试对象生命周期管理方法 -->
	<bean id="demo"	class="day01.DemoBean"
		lazy-init="true"
		init-method="init" destroy-method="destroy"/>
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值