Day43-Spring和Ioc

总结

我是最棒的!基础不牢,地动山摇!

Spring

它是一个轻量级的DI/IOC,AOP的框架,主要是一个javabean容器,主要存储对象

框架

它就是一个半成品的工具,把一些公共的部分给抽取出来封装成对应的方法和jar包,直接调用即可,不需要手动编写

轻量级和重量级

描述一个框架是一个轻量级还是重量级不是指轻和重,其实指的就是一个框架好不好用

IOC

控制反转,把当前应用软件中所有的对象的控制权交给Spring管理

DI

依赖注入,赋值操作

AOP

面向切面编程,解耦,抽取公共业务逻辑代码,扩展功能十分简单

Spring创建对象的方式

applicationContext.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" >

	 <!-- 
	 	bean:代表我要交给spring管理 
	 	id:bean的别名,必须独一无二
	 	class:交给spring管理的bean
	 	
	 	MyBean  myBean = new MyBean();
	 -->
	 <bean id="myBean" class="cn.itsource.bean.MyBean"></bean>
	 <bean id="myBean2" class="cn.itsource.bean.MyBean"></bean>
	 <bean id="myBean3" class="cn.itsource.bean.MyBean"></bean>
</beans>
        

测试代码

package cn.itsource.bean;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainTest {
	@Test
	public void test1() throws Exception {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		//通过名字获取bean对象,如果没找到会报错
		MyBean bean = (MyBean) applicationContext.getBean("myBean");
		System.out.println(bean);
		//通过类型获取bean对象,如果多个相同类型的对象就会报错
		MyBean bean2 = applicationContext.getBean(MyBean.class);
		System.out.println(bean2);
		//通过类型和名字获取bean对象
		MyBean bean3 = applicationContext.getBean("myBean2", MyBean.class);
		System.out.println(bean3);
		
		MyBean bean4 = applicationContext.getBean("myBean3", MyBean.class);
		System.out.println(bean4);
	}
}

BeanFactory和ApplicationContext的区别

ApplicationContext的功能更强大,它支持国际化和直接解析xml文件的功能。

这两者创建对象的时机是不一样的,BeanFactory是懒加载,在真正使用该对象时才会去创建该对象。而ApplicationContext创建对象是迫切加载,不管用不用该对象,交给spring管理之后都会提前把对象创建好。

Spring测试

以前单纯的Junit测试,是先运行单元测试,最后启动spring容器

spring测试的特点是先启动spring容器,再去启动单元测试

Spring作用域

交给spring管理的bean默认都是单例的(从创建到销毁都是spring完成的),可以通过更改scope属性值为prototype成为多例,但是多例的销毁spring不会执行,而是由垃圾回收机制来处理

<bean class="cn.itsource.scope.Scope" scope="prototype"></bean>

Spring的生命周期

一个例子来说明

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" >

	 <bean class="cn.itsource.life.MyBean" init-method="init" destroy-method="destroy"></bean>
</beans>
        

MyBean

package cn.itsource.life;

public class MyBean {
	public MyBean() {
		System.out.println("构造方法");
	}
	
	public void init(){
		System.out.println("初始化方法");
	}
	
	public void service(){
		System.out.println("服务方法");
	}
	
	public void destroy(){
		System.out.println("销毁方法");
	}
}

测试

package cn.itsource.life;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class MainTest {
	
	@Autowired
	private MyBean myBean;
	
	@Test
	public void testMain(){
		myBean.service();
	}
}

结果如下

构造方法
初始化方法
服务方法
十月 08, 2019 7:29:53 下午 org.springframework.context.support.AbstractApplicationContext doClose
信息: Closing org.springframework.context.support.GenericApplicationContext@19dfb72a: startup date [Tue Oct 08 19:29:52 CST 2019]; root of context hierarchy
销毁方法

Spring属性注入

<?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中的property来设置属性
	 	name为属性名 (一般的属性8大基本数据类型及包装类和String用value来设置值)
	 	ref为引用(当bean中有其他属性使用ref)
	 -->
	 <bean id="otherBean" class="cn.itsource.property.OtherBean">
	 	<property name="name" value="wdnmd"/>
	 </bean>
	 
	 <bean id="myBean" class="cn.itsource.property.MyBean">
	 	<property name="id" value="1"/>
	 	<property name="name" value="cdd"/>
	 	<property name="otherBean" ref="otherBean"/>
	 </bean>
</beans>
        

三层架构

Controller 控制层 接收参数,调用Service层的业务处理逻辑,控制页面跳转

Service 业务层 写业务逻辑,调用Dao层来实现crud的逻辑

Dao 持久层 sql语句直接操作数据库

目的:解耦,扩展性更强

原生三层架构

通过手动创建对象写死来实现,Service层中手动创建一个IUserDao对象,再调用方法,Controller层中手动创建一个IUserService对象,再调用方法。

Spring管理三层架构

通过依赖注入来实现

<?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 id="userDao" class="cn.itsource.threelayers.dao.impl.UserDaoImpl"></bean>
	 
	 <bean id="userService" class="cn.itsource.threelayers.service.impl.UserServiceImpl">
	 	<property name="userDao" ref="userDao"/>
	 </bean>
	 
	 <bean class="cn.itsource.threelayers.controller.UserController">
	 	<property name="userService" ref="userService"/>
	 </bean>
</beans>
        

UserService的实现类

package cn.itsource.threelayers.service.impl;

import cn.itsource.threelayers.dao.IUserDao;
import cn.itsource.threelayers.domain.User;
import cn.itsource.threelayers.service.IUserService;

public class UserServiceImpl implements IUserService {

	private IUserDao userDao;

	public void setUserDao(IUserDao userDao) {
		this.userDao = userDao;
	}

	@Override
	public void save(User user) {
		userDao.save(user);
	}

}

需要我们注意的是,domain中的对象都需要我们自己来手动创建。

Spring管理dbcp连接池

通过写jdbc的配置文件和我们的xml文件关联起来。再将dataSource给spring管理,设置属性

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
    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
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd" >

	 <context:property-placeholder location="classpath:jdbc.properties"/>
	 
	 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
	 	<property name="username" value="${jdbc.username}"></property>
	 	<property name="password" value="${jdbc.password}"></property>
	 	<property name="url" value="${jdbc.url}"></property>
	 	<property name="driverClassName" value="${jdbc.driverClassName}"></property>
	 </bean>
</beans>
        

每个属性的value前面加上jdbc前缀是因为不加前缀会和系统的用户名冲突,它默认使用当前电脑登录的用户名

猜你喜欢

转载自blog.csdn.net/t384061961/article/details/102420211