总结
我是最棒的!基础不牢,地动山摇!
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前缀是因为不加前缀会和系统的用户名冲突,它默认使用当前电脑登录的用户名