主流框架学习——SpringIoC

一、程序的耦合和解耦

1、耦合(程序间的依赖关系)
a、类之间的依赖
b、方法间的依赖

2、解耦(应该做到编译器不依赖,运行时依赖)
a、降低程序间的依赖关系

b、思路
1,使用反射来创建对象,而避免使用new关键字
2,通过读取配置文件来获取要创建的对象全限定类名

3、解决方案
a、创建Bean工厂(bean:可重用组件)

	/*
		例如:service和dao对象
	  	service 依赖于 dao
	  	两者的impl也依赖于本体

	1,需要一个配置文件来配置我们的service和dao配置的内容:唯一标识=全限定类名(key=value)
	2,通过读取配置文件中的配置的内容,反射创建

	配置文件可为xml或properties
	*/
	
	//配置bean.properties
	accountService=com.learn.service.impl.AccountServiceImpl
	accountDao=com.learn.dao.impl.accountDaoImpl

	//编写BeanFactory
	public class BeanFactory{
		//定义一个properties对象
		private static Properties props;

		//定义一个Map(容器),用于存放我们要创建的对象
		private static Map<String,Object> beans;
		
		//使用静态代码块为Properties赋值
		static{
			try{
				//实例化对象
				props = new Properties();
				//获取properties问价你的流对象
				InputStream in = BeanFactory.class.getClassLoader()
				.getResourceAsStream("bean.properties");
				props.load(in);
				//实例化容器
				beans = new HashMap<String,Object>();
				//取出配置文件中所有的key
				Enumeration<String> keys = props.keys();
				while(keys.hasMoreElements()){
					//取出每个Key
					String key = keys.nextElement().toString();
					//根据key获取value
					String beanPath = props.getProperty(key);
					//反射创建对象
					Object value = Class.forname(beanPath).newInstance();
					//把key和value放入容器中
					beans.put(key,value);
				}
			}catch(Exception e){
				throw new ExceptionInInitializerError("初始化失败");
			}
		}
	
		//根据Bean名称获取bean对象
		public static Object getBean(String beanName){
			return beans.get(beanName);
		}
	}

	//则再客户端或者实现类中,可用BeanFactory.getBean("配置的名称")
	IAccountService as = BeanFactory.getBean("accountService");

2、Spring的IoC解决程序耦合
a、概念(控制反转(IoC)把创建对象的权利交给框架)

b、主要jar包(jar包依赖关系同)
1,spring-bean-5.0.2.RELEASE.jar
2,spring-context-5.0.2.RELEASE.jar
3,spring-core-5.0.2.RELEASE.jar
4,spring-expression-5.0.2.RELEASE.jar
5,spring-aop-5.0.2.RELEASE.jar
6,spring-jcl-5.0.2.RELEASE.jar

在这里插入图片描述
c、基本环境搭建

//配置bean.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
        
	//把对象的创建交给spring来管理
    <bean id="accountService" class="com.learn.service.impl.AccountServiceImpl">
        
    </bean>

    <bean id="accountDao" class="com.learn.dao.impl.AccountDaoImpl">
        
    </bean>
</beans>

//获取spring的IoC核心容器,并根据id获取对象
public class Client{
	public static void main(){
		/*
			ApplicationContext:在构建核心容器时,创建对象采取的策略是立即加载的方式
			BeanFactory:在构建核心容器时,创建对象采取的策略是延迟加载的方式(当根据id获取对象时,才真正创建对象)
			获取核心容器对象 
		*/
		ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
		
		/*
			根据id获取Bean对象
			可用(IAccountService)ac.getBean("accountService")进行强转
			ad.getBean("accountDao",IAccountDao.class)通过字节码进行强转
		*/
		IAccountService as = (IAccountService)ac.getBean("accountService");
		IAccountDao ad = ad.getBean("accountDao",IAccountDao.class);

		System.out.println("as="+as+"ad="+ad);
	}	
} 

d、spring对bean的管理细节
1,创建bean的三种方式

	//使用默认构造函数创建
	<bean id="accountService" class="com.learn.service.impl.AccountServiceImpl"></bean>

	/*
		创建一个实例化工厂类,在里面定义getAccountService方法
		使用普通工厂中的方法创建对象(使用类中的方法创建对象,并存入spring容器)	
	*/
	<bean id="instanceFactory" class="com.learn.factory.InstanceFactory"></bean>
	<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>

	/*
		创建一个实例化工厂类,在里面定义getAccountService的静态方法
		使用普通工厂中的方法创建对象(使用类中的方法创建对象,并存入spring容器)
	*/
	<bean id="accountService" class="com.learn.factory.StaticFactory" 
	 factory-method="getAccountService"></bean>

2,bean的作用范围(使用bean标签里的scope标签)

①:取值,通常是单例或者多例

singleton单例的(默认值)
prototype多例的
request作用于web应用的请求范围
session作用于web应用的会话范围
golbal-session作用于集群环境会话范围(全局会话范围),当不是集群环境时,它就是session
3,生命周期

①:单例对象

出生当容器创建时对象出生
活着只要容器还在,对象就一直活着
死亡容器销毁,对象消亡
总结单例对象的生命周期和容器相同

②:多例对象

出生当我们使用对象时,spring框架为我们创建
活着对象使用过程中一直活着
死亡对象长时间不用,且没有别的对象应用时,由java的垃圾回收器回收

3、依赖注入
a、概念
1,在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明
2,依赖关系的维护(依赖注入)
3,依赖关系的管理(交给spring来维护)

4,能注入的数据类型

①:基本数据类型和String
②:其他bean类型(在配置文件中或者注解配置过的bean)
③:复杂关系/集合类型

5,注入方式

①:构造函数提供
②:set方法提供(主要方式)
③:注解提供(主要方式)

b、set方法注入

	/*
		property标签属性:
			name:用于指定注入时所调用的set方法
			value:用于提供基本类型和String类型的数据
			ref:用于指定其他的bean类型数据。
	*/
	
	//配置的日期对象
	<bean id="now" class="java.util.Date">
	
	<bean id="accountService" class=""com.learn.service.impl.AccountServiceImpl>
		<property name="name" value="zhangsan"></property>
		<property name="age" value="18"></property>
		<property name="birthday" ref="now"></property>
	</bean>

	/*
		复杂类型的注入/集合类型的注入
		list结构集合注入的标签:
			list array set
		Map结构集合注入的标签:
			map props
		结构相同时,标签可以互换
	*/
	<bean id="accountService" class=""com.learn.service.impl.AccountServiceImpl>
		//list
		<property name="myList">
			<list>
				<value>aaa</value>
				<value>bbb</value>
			</list>
		</property>
		
		//Map结构
		<property name="myProps">
			<map>
				<entry key="testA" value="aaa"></entry>
				<entry key="testB" value="bbb"></entry>
			</map>
		</property>
	</bean>

二、Spring基于注解配置IoC

1、常用注解

注解名称作用
@Component用于把当前类对象存入spring容器中
@Autowired自动按照类型注入,只要容器中有唯一匹配的bean对象,就可以成功注入
@Qualifier在按照类中注入的基础之上,再按名称注入
@Value用于指定注入基本类型和String类型的数据
@Scope用于指定bean的作用范围(常用取值:singleton prototype)
@PreDestory指定销毁方法
@PostConstruct用于指定初始化方法)
只能通过bean.xml配置集合类型

a、@Component
1,作用:用于把当前类对象存入spring容器中
2,属性:value用于指定bean的id(默认为当前类名且首字母改小写)

3,相同作用与属性的注解(Spring框架提供三层使用的注解)

①:Controller 表现层
②:Service 业务层
③:Repository 持久层

b、@Qualifier
1,配合@Autowired对类进行精确的注入

	//注入accountDao1
	@Autowired
	@Qualifier("accountDao1")
	private IAccountDao accountDao;

c、@Resource

	@Resource("accountDao1")
	private IAccountDao accountDao;

d、@Value

①:可以使用Spring中的spEL(el表达式)
②:SpEL写法:$(表达式)

2、环境搭建

	/*
		配置bean.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:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
	
	//告知spring在创建容器时要扫描的包,配置所需要的的标签不只是在beans的约束中,
	//而是一个名为context名称空间和约束中
	<context:component-scan base-packing="com.learn"></context:component-scan>
</beans>	

	//配置AccountServiceImpl
	@Component
	public class AccountService implenments IAccountService{
		
		@Autowired
		private IAccountDao accountDao;
		
		public AccountServiceImpl(){
			System.out.println("对象创建完成")		
		}
	}
	
	//获取spring的IoC核心容器,并根据id获取对象
	public class Client{
		public static void main(){
			ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
			
			//根据id获取Bean对象
			IAccountService as = (IAccountService)ac.getBean("accountServiceImpl");
			System.out.println("as="+as);
		}	
	} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值