1 spring简介
1.1 spring是什么?
Spring是分层Java SE/EE应用full-stack轻量级开源框架,以loC(Inverse Of Control)和AOP(Aspect Oriented Programming)为内核。
提供了展示层springMVC和持久层spring JDBCTemplate 以及业务事务管理等众多的企业级应用技术,还能整合开源框架和类库,逐渐成为使用最多的Java EE企业应用开源框架。
1.2 spring的优势
1) 方便解耦,简化开发
通过spring提供的loC容器,可以将对象间的依赖交由spring进行控制,避免硬编码的过度耦合。用户也不必为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
2) AOP编程支持
通过spring的AOP功能,方便进行面向切面编程,许多不容易用传统OOP实现的功能可以通过AOP轻松实现。
3) 声明式事务支持
可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务管理,提升开发效率和质量。
4) 方便程序的测试
可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做。
5) 方便集成优秀框架
Spring对各种优秀框架的支持。(struts、Hibernate、Hessian、Quart)
6) 降低JavaEE API的使用难度
Spring对JavaEE API(jdbc,javamail)进行薄薄的封装层,使这些API的使用难度大为降低
7) Java源码是经典学习范例
源代码设计巧妙、结构清晰、匠心使用,体现对Java设计模式的应用和Java技术的高深造诣。
1.3 spring的体系结构
2. spring快速入门
2.1 spring开发步骤
1) 导入spring开发的依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
2) 编写dao接口和实现类Bean
@Override
public void save() {
System.out.println("=====save dao11111111 ==========");
}
- 创建spring核心配置文件applicationContext.xml
- 在spring配置文件中配置UserDaoImpl
<bean id="userDao" class="cn.hfnu.dao.impl.UserDaoImpl"></bean>
- 使用spring的API获得Bean实例 getBean
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao1 = (UserDao) app.getBean("userDao");
UserDao userDao2 = (UserDao) app.getBean("userDao");
System.out.println("=======userDao1=====>"+userDao1);
System.out.println("=======userDao2=====>"+userDao2);
userDao1.save();
userDao2.save();
3. spring配置文件
3.1 Bean标签基本配置
用于配置对象由spring来创建,默认情况它调用类中的无参构造函数
基本属性:
id: bean实例在spring容器的唯一标识
class: bean的全限定名
3.2 bean标签的范围配置
scope: 指对象的作用范围
singleton: 默认值,单例的
prototype: 多例的
request:web项目,spring创建bean对象,并将对象存入request域
session: web项目,spring创建bean对象,并将对象存入session域
global session: web项目中应用portlet环境,如果没有portlet环境那么globalsession相当于session
<bean id="userDao" class="cn.hfnu.dao.impl.UserDaoImpl" scope="singleton"></bean>
<bean id="userDao" class="cn.hfnu.dao.impl.UserDaoImpl" scope="prototype"></bean>
1) 当scope取值singleton时
bean的实例化个数:1个
bean实例化时机:spring核心配置文件applicationContext.xml被加载,实例化配置bean实例
bean的生命周期:
对象创建:当应用加载,创建容器时,对象被创建
对象运行:只要容器在,对象就一直活着
对象销毁:当应用卸载,销毁容器,对象被销毁
2) 当scope取值prototype时
bean的实例化个数:多个
bean实例化时机:当getbean()方法实例化bean
对象创建:当使用对象时,创建新的对象实例
对象运行:只要对象再使用中,对象一直活着
对象销毁:当对象长时间不用时,被java垃圾回收器回收
3.3 bean生命周期配置
init-method: 指定类中的初始化方法名称
destroy-method: 指定类中销毁方法名称
<bean id="userDao" class="cn.hfnu.dao.impl.UserDaoImpl" scope="singleton" init-method="init" destroy-method="destroy"></bean>
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao1 = (UserDao) app.getBean("userDao");
UserDao userDao2 = (UserDao) app.getBean("userDao");
System.out.println("=======userDao1=====>"+userDao1);
System.out.println("=======userDao2=====>"+userDao2);
userDao1.save();
userDao2.save();
app.close();
3.4 bean实例化三种方式
1)无参构造实例化(重点)
//无参构造
public UserDaoImpl() {
System.out.println("=========UserDaoImpl对象被创建=========");
}
2)工厂静态实例化
<bean id="userDao" class="cn.hfnu.fatory.StaticFactory" scope="singleton" factory-method="getUserDao"></bean>
public static UserDao getUserDao(){
System.out.println("==========静态工厂=======");
return new UserDaoImpl();
}
3)工厂实例化
<bean id="factory" class="cn.hfnu.fatory.DynamicFactory"></bean>
<bean id="userDao" factory-bean="factory" factory-method="getUserDao"></bean>
3.5 bean依赖注入分析
因为UserService和UserDao都在spring容器中,而最终程序直接使用UserService, 所以在spring容器中,将UserDao设置到UserService内部
3.6 bean依赖注入的概念
依赖注入(Dependency Injection):它是spring容器核心的IoC具体实现。
将bean对象的实例存到spring容器中,从外部获得bean实例与程序进行结合,设置bean对象到spring容器中。
编写程序时,通过控制反转(Inverse of Controller),将对象创建交给了spring容器管理,IoC解耦只能降低他们的依赖关系,但不会消除。
将service层对象通过spring容器交给controller层,dao层对象交给service层,bean对象交到spring容器中就由spring容器来维护了。
3.7 bean的依赖注入
将userdao注入到userservice内部?
- 构造方法注入:
private UserDao userDao;
public UserServiceImpl() {
}
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
<bean id="userDao" class="cn.hfnu.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="cn.hfnu.service.impl.UserServiceImpl">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
- set方法注入:p命名空间注入本质也是set方法注入
<bean id="userDao" class="cn.hfnu.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="cn.hfnu.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
需要引入P命名空间:
xmlns:p="http://www.springframework.org/schema/p"
需要修改注入方式:
<bean id="userService" class="cn.hfnu.service.impl.UserServiceImpl" p:userDao-ref="userDao"/>
3.8 bean的依赖注入的数据类型
1)普通数据类型注入:
private String username;
private int age;
private String gender;
public void setUsername(String username) {
this.username = username;
}
public void setAge(int age) {
this.age = age;
}
public void setGender(String gender) {
this.gender = gender;
}
<bean id="userDao" class="cn.hfnu.dao.impl.UserDaoImpl">
<property name="username" value="曹操"></property>
<property name="age" value="20"></property>
<property name="gender" value="男"></property>
</bean>
2)引用数据类型注入:
3)集合数据类型注入:
//集合
private List<String> list;
private Map<String, User> map;
private Properties properties;
public void setList(List<String> list) {
this.list = list;
}
public void setMap(Map<String, User> map) {
this.map = map;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
<bean id="userDao" class="cn.hfnu.dao.impl.UserDaoImpl">
<property name="list">
<list>
<value>诸葛亮</value>
<value>曹操</value>
<value>孙权</value>
</list>
</property>
<property name="map">
<map>
<entry key="1001" value-ref="user1"></entry>
<entry key="1002" value-ref="user2"></entry>
<entry key="1003" value-ref="user3"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="A001">aaa</prop>
<prop key="A002">bbb</prop>
<prop key="A003">bbb</prop>
</props>
</property>
</bean>
<bean id="user1" class="cn.hfnu.pojo.User">
<property name="uid" value="1001"></property>
<property name="username" value="zhangsan"></property>
<property name="age" value="18"></property>
<property name="pwd" value="123"></property>
</bean>
<bean id="user2" class="cn.hfnu.pojo.User">
<property name="uid" value="1002"></property>
<property name="username" value="lisi"></property>
<property name="age" value="22"></property>
<property name="pwd" value="123"></property>
</bean>
<bean id="user3" class="cn.hfnu.pojo.User">
<property name="uid" value="1003"></property>
<property name="username" value="wangwu"></property>
<property name="age" value="20"></property>
<property name="pwd" value="123"></property>
</bean>
3.9 引入其他配置文件
实际开发中spring的配置内容非常多,导致spring配置很繁杂且体积很大,所以可以将部分配置拆解到其他配置文件中,在spring主配置文件通过import标签进行加载。
<import resource="applicationContext_user.xml" />
4. spring相关的API
4.1 applicationcontext的继承体系
applicationcontext: 接口类型,代表应用上下文,可以通过其实例获得spring容器的bean对象
4.2 applicationcontext的实现类
4.3 getBean() 方法使用
当参数的数据类型是字符串时,表示bean的id从容器中获取bean实例,返回object需要强转。当参数数据类型是class类型,表示根据类型从容器中匹配bean实例,当容器中相同类型的bean有多个时,此方法会报错。
5 spring配置数据源
5.1 数据源(数据连接池)的作用
数据源是提高程序性能
事先实例化数据源,初始化部分连接资源
使用连接资源时从数据源中获取
使用完毕后将连接资源归还给数据源
6. spring注解开发
6.1 spring的原始注解
spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,注解代替xml配置文件可以简化配置,提高开发效率。
spring原始注解主要替代<bean>的配置
@Component 使用在类上用于实例化Bean
@Controller 使用在web层类上用于实例化bean
@Service 使用在service层类上用于实例化bean
@Repository 使用在dao层类上用于实例化bean
@Autowired 使用在字段上用于根据类型依赖注入
@Qualifier 结合@Autowired一起使用用于根据名称进行依赖注入
@Resource 相当于@Autowired + @Qualifier,按照名称进行注入
@Value 注入普通属性
@Scope 标注bean的作用范围
@PostConstruct 使用在方法上标注该方法是bean的初始化方法
@PreDestroy 使用在方法上标注该方法是bean的销毁方法
//<bean id="studentDao" class="cn.hfnu.dao.impl.StudentDaoImpl"></bean>
@Component
//<bean id="studentService" class="cn.hfnu.service.impl.StudentServiceImpl"></bean>
@Component
@Autowired
@Qualifier("studentDao")
private StudentDao studentDao;
使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包及其子包下的bean需要进行扫描以便识别使用注解配置的类、字段和方法。
<!--配置组件扫描包-->
<context:component-scan base-package="cn.hfnu"/>
6.2 spring的新注解
非自定义的bean的配置:<bean>
加载properties文件配置:
组件扫描的配置:
引入其他文件:<import>
@Configuration 用于指定当前类是一个spring配置类,当创建容器时会从该类上加载注解
@ComponentScan 用于指定spring在初始化容器要扫描的包。
@Bean 使用在方法上,标注将该方法的返回值存储到spring容器中
@PropertySource 用于加载.properties 文件中配置
@Import 用于导入其他配置类
7 spring集成junit
7.1 原始junit测试spring的问题
这两行代码的作用是获取容器,如果不写,提示空指针异常。不能轻易的删除。
7.2 上述问题的解决方案
让springjunit负责创建spring容器,但是需要将配置文件的名称告诉它 将需要进行测试的bean直接在测试类中进行注入
7.3 spring集成junit步骤
导入spring集成junit的坐标
使用@Runwith注解替换原来的运行期
使用@ContextConfiguration指定配置文件或配置类
使用@Autowired注入需要测试的对象
创建测试方法进行测试
8 spring集成web环境
8.1 applicationcontext应用上下文获取方式
应用上下文对象是通过new ClassPathXmlApplicationContext("applicationContext.xml")方式获取的,但是每次从容器中获得bean时都要
new ClassPathXmlApplicationContext("applicationContext.xml"),这样的弊端是配置文件被加载多次,应用上下文对象创建多次。
在web项目中,可以使用servletcontextlistener监听web项目启动,我们可以在web项目中启动时,加载spring配置文件,创建应用上下文对象applicationcontext,在将其存储到最大的域servletcontext域中,这样就可以在任意位置从域中获得应用上下文applicationcontext对象。
如果你认真阅读到这里相信你对Spring入门有了一定的收获。以上这篇博客是对自己的学习过程的记录,坚持一件事不容易,我们的目标和人民日报站在一起!如果你在看,请坚持点个“在看”,点个“赞”,你个在看你会变好看。