Spring入门一:IOC、DI、AOP基本思想
Spring框架是一个集众多涉及模式于一身的开源的、轻量级的项目管理框架,致力于javaee轻量级解决方案。相对于原来学过的框架而言,spring框架和之前学习的struts2、mybatis框架有了本质的区别,不是替换原来的某个框架,而是对其进行整合管理。
轻量级解决方案:提供一个简单的,统一的、高效的方式构造整个应用,并且可以将单层框架以最佳的组合柔和在一起建立一个连贯的体系。
核心思想:IOC(控制反转),DI(依赖注入),AOP(面向切面编程)。
一、环境搭建
1、引入核心依赖及相关依赖:
<!-- https://mvnrepository.com/artifact/org.springframework/ --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.3.5</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.3.5</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.3.5</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.3.5</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.5</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.3.5</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.3.5</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.3.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.4</version> </dependency>
2、引入spring框架配置文件:
配置文件名称随意(applicationContext.xml获取spring.xml),位于resources目录下面即可。
<?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:用来指定管理对象的全限定名 id:用来指定spring框架创建的当前组件对象在spring中唯一标识 --> <bean class="com.icucoder.spring.dao.impl.UserDaoImpl" id="userDao"></bean> </beans>
3、获取bean
假设com.icucoder.spring.dao下面有UserDao和UserDaoImpl,可以通过ClassPathXmlApplicationContext获取spring配置文件中配置的bean。
public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); UserDao userDao = (UserDao) context.getBean("userDao"); userDao.save("测试spring配置文件"); }
二、IOC和DI思想
1、IOC:控制反转
通过在配置文件中使用bean标签而不是通过关键字new的方式创建对象的过程。
2、DI:依赖注入
为组件中的成员变量完成赋值的过程。
语法:
(1)组件对象中需要哪个组件,就将该组件声明为成员变量并提供公开的SET方法。
(2)在spring配置文件中对应的bean标签内完成属性的赋值操作。
三、注入方式
1、setter注入
在组件内使用成员变量setter方法的方式赋值。
除了注入组件对象(使用ref),也可以注入其他类型的数据(如:八种基本类型数据使用value)。
语法:
(1)定义需要的组件成员变量,并提供公开的setter方法:
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void save(String name) {
userDao.save(name);
}
}
(2)在spring配置文件中该组件的bean标签内配置<property>标签进行赋值操作:
<bean class="com.icucoder.spring.dao.impl.UserDaoImpl" id="userDao"></bean>
<bean class="com.icucoder.spring.service.impl.UserServiceImpl" id="userService">
<property name="userDao" ref="userDao"/>
</bean>
2、构造注入
使用类中构造方法为类中成员变量赋值过程,称之为构造注入。
除了注入组件对象(使用ref),也可以注入其他类型的数据(如:八种基本类型数据使用value)。
语法:
(1)需要哪个组件属性将谁声明为成员变量,提供公共构造方法:
public class CompanyServiceImpl implements CompanyService {
private CompanyDao companyDao;
public CompanyServiceImpl(CompanyDao companyDao) {
this.companyDao = companyDao;
}
public void save(String name) {
companyDao.save(name);
}
}
(2)在配置文件中对应的bean标签内部使用<constructor-arg>标签进行注入:
<bean class="com.icucoder.spring.dao.impl.CompanyDaoImpl" id="companyDao"></bean>
<bean class="com.icucoder.spring.service.impl.CompanyServiceImpl" id="companyService">
<constructor-arg index="0" name="companyDao" ref="companyDao"/>
</bean>
3、自动注入
通过在配置文件中通过制定自动注入方式开启组件属性自动赋值。
注意:底层使用的原理也是SET方式注入;自动注入需要在对应组件标签开启才能使用。只能用于引用类型、对象类型、组件类型的注入。
语法:
(1)需要谁将谁声明为成员变量,并提供SET方法:
(2)在对应组件标签中加入autowired属性,并指定自动注入方式即可完成注入:
<bean class="com.icucoder.spring.dao.impl.AddrDaoImpl" id="addrDao"></bean> <!--autowire:用来给组件中成员变量完成自动赋值操作 byType:根据类型完成自动注入(去工厂中找,找到对应的类型完成赋值,找不到不赋值) byName:根据名称完成自动注入(去工厂中找,找到对应的名字完成赋值,找不到不赋值) --> <bean class="com.icucoder.spring.service.impl.AddrServiceImpl" id="addrService" autowire="byName"></bean>
四、spring工厂的相关特性
1、bean的创建方式
1)singleton:单例模式(默认)
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); UserService userService1 = (UserService) context.getBean("userService"); UserService userService2 = (UserService) context.getBean("userService"); System.out.println(userService1 == userService2);//true
service、dao单例形式管理
2)prototype:多例模式
<bean class="****" id="***" scope="prototype"></bean>
struts2的action之类的必须以多例形式管理
2、bean的生产原理
原理:反射+构造方法
UserService userService = (UserService) Class.forName("com.icucoder.spring.service.impl.UserServiceImpl").newInstance(); System.out.println(userService);
3、bean的生命周期
单例对象和多例对象的生命周期是不一样的。
<bean class="****" id="***" scope="singleton" init-method="***" destroy-method="***"></bean>
1)单例对象
工厂启动工厂中所有单例的对象随之创建,工厂正常销毁(context.close())工厂中所有单例对象随之销毁。
2)多例对象
每次在工厂中使用时创建,工厂不负责多例对象的销毁,由jvm负责销毁。
4、spring工厂的好处
(1)解耦合:使用配置文件管理java类,在生产环境中更换类的实现时不需要重新部署,修改文件即可。
(2)spring默认使用的是单例模式创建Bean,减少内存占用。
(3)通过依赖注入建立了类与类之间的关系(使java之间关系更为清晰,方便了维护与管理)。
五、AOP思想
1、代理的概念
1)代理对象
作用:在整个业务逻辑中完成传话(附件操作)的作用,同时也可以中断整个业务;
好处:既可以保证原始业务逻辑、原始业务功能不变的同时还可以完成一些附加操作;
2)如何开发一个代理对象
(1)代理对象和业务逻辑对象(真正业务逻辑对象或目标对象)实现相同的接口;
(2)代理对象中依赖真正业务逻辑对象;
3)代理分类
静态代理:为每一个业务层通过手动开发一个代理对象的过程;
动态代理:在程序运行的过程中动态通过代码的方式为指定的类生成动态代理对象;(Proxy用来生成动态对象的类)
2、AOP概念
通知(Advice):除了目标方法以外的操作都称之为通知(环绕通知、前置通知、后置通知、异常通知);如事物通知、日志通知、性能通知;
切入点(Pointcut):指定开发好的通知应用于项目中哪些组件中的哪些方法;一般通知多用于业务层;
切面(Aspect):等价于通知+切入点;
AOP编程:①开发通知类(附件功能)②配置切入点 ③组装切面
3、AOP切面编程
基本步骤
①引入aop相关依赖:spring-aop、spring-expression、spring-aspect
②开发额外功能的通知:环绕通知MethodIntercept、前置通知MethodBeforeAdvice、后置通知AfterReturnAdvice、异常通知ThrowsAdvice
③配置切面:spring.xml
a)注册通知类:<bean id="" class=""/>
b)组装切面 aspect=advice+pointcut:<aop:config><aop:pointcut/><aop:advisor/></aop:config>
④创建service组件
⑤测试
1)环绕通知-MethodIntercept
2)前置通知-MethodBeforeAdvice
3)后置通知-AfterReturnAdvice
4)异常通知-ThrowsAdvice
六、Spring中创建复杂对象
如果你真心觉得文章写得不错,而且对你有所帮助,那就不妨小小打赏一下吧,如果囊中羞涩,不妨帮忙“推荐"一下,您的“推荐”和”打赏“将是我最大的写作动力!
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接.