一、spring概述
1、定义
spring 框架是一个开源的框架, SPring当中两个人核心IOC(控制反转/依赖注入),AOP(面向切面编程) ,Spring框架类似一个大型的容器,把各个层次都整合在一起。在每个层次都提供了解决方案、 Spring被称之为一站式框架。
Web: Springmvc 技术,取代Servlet
Service: 提供了事务的管理: bean对象的管理:
Dao: JdbcTemplate 对象, 完成jdbc的封装---->DBUtils
ORM模块, 整合其他的优秀的ORM框架。Mybatis/Hibernate等
2、spring优点
(1)方便解耦,简化开发:通过spring提供的IOC容器,可以将对象之间的依赖关系交给spring控制,避免了硬编码所造成的过度程序耦合。有了spring,用户就不需要为单实例模式类、属性文件解析等底层需求编写代码,可以专注于上层开发。
(2)AOP编程的支持:通过spring提供的aop功能,方便进行面向切面的编程,许多不容易用传统oop实现的功能可以通过aop实现。
(3)声明式事务的支持:在spring中可以用声明式的方式进行事务的管理,来代替繁琐的事务管理代码,提高开发效率和质量。
(4)方便程序的测试:在sprig中可以用非容器依赖的编程方式进行几乎所有的测试工作,如,spring对Junit4支持,可通过注解测试spring程序。
(5)方便集成各种优秀框架:spring不排斥各种优秀的开源框架,反而降低了各种框架的使用难度,spring提供了对各种优秀框架(如Struts、hibernate、hessian、quartz、mybatis)等的直接支持。
(6)降低了javaEE API的使用难度:spring对很多比较难用的javaEE API(如jdbc、JavaMail、远程调用等)提供了一个薄薄的封装层,通过spring的简易封装,这些API的使用难度大大降低了。
二、解耦合
1、使用properties方式
<beans>
<bean id=”product” class=””> </bean>
<bean id=”order” class=””> </bean>
<bean id=”item” class=””> </bean>
</beans>
2、使用xml方式
public static Object createObject(String name) {
try {
//通过传递过来的name获取application.xml中name对应的class值
//获取到Document对象
SAXReader reader=new SAXReader();
//如果获取application.xml文件的输入流 (application.xml必须位于src下)
InputStream is=BeanFactory.class.getClassLoader().getResourceAsStream("application.xml");
Document doc=reader.read(is);
//通过Document对象获取根节点 beans
Element rootElement = doc.getRootElement();
//通过根节点获取到根节点下所有的子节点 bean,返回集合
List<Element> list = rootElement.elements();
//遍历集合,判断每个元素上的id的值是否和当前的name一致
for (Element ele : list) {
//ele相当于beans节点下的每个bean
//获取到当前节点的id属性值,如果一致,获取到当前元素上class属性值
String id=ele.attributeValue("id");
if(id.equals(name)){
String str=ele.attributeValue("class");
//通过反射创建对象并且返回
Class clazz=Class.forName(str);
//利用class值通过反射创建对象返回
return clazz.newInstance();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
三、IOC
(1)定义:
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。 将 对象创建的权利交给了spring框架。 而不再是程序员创建。
(2)引入spring框架的核心配置文件:
在src下创建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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
">
<!-- UserDaoImpl对象的初始化操作交给了spring: -->
<bean id="userDao" class="UserDaoImpl的全路径"
init-method="init" destroy-method="destory"
scope="prototype"></bean>
</beans>
bean属性详解:
①bean:初始化bean对象
②id:给被管理对象起的名字,获得对象是getBean(“id的值”)
③class:被管理对象的完整类名
④init-method:bean被初始化时执行的方法
⑤destroy-method:bean被销毁的时候执行的方法
⑥scope:Bean的作用范围相关的属性
singleton :默认的,Spring会采用单例模式创建这个对象。 对象的创建时机, 配置文件读取, 对象就会创建完成,存在spring容器当中。 被标识为单例的对象在spring容器中只会存在一个实例。
prototype :多例模式。(Struts2和Spring整合一定会用到) 对象的创建时机,并不是读取配置文件的时候,而是当从spring当中获得对象的时候, 对象创建,并且每获得一次,对象创建一次新的对象。与struts整合时候,务必要用prototype多例,因为struts2在每次请求都会创建一个新的Action,若为单例,在多请求情况下,每个请求找spring拿的都是同一个action。
注解完成IOC操作
1)@Component :用于实现ioc控制反转,属性value用于实现对象id定义
2)@Scope :用于实现单例,多例,request,session等的配置
3)@Controller : 专门用于controller层的注解,实现控制反转,属性value
4)@Service : 专门用于service层的注解,实现控制反转,属性value
5)@Repository : 专门用于持久层的注解,实现控制反转,属性value
(3)DI依赖注入:
定义:Dependency Injection依赖注入 , sprinig 框架在创建对象的时候,需要对对象的属性进行初始化操作, 这个过程就是DI
<!--在spring中进行userserviceimpl对象的初始化 -->
<!-- set注入
<bean id="userService" class="com.xhx.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
<property name="username" value="set注入"></property>
</bean> -->
<!-- 构造器注入 constructor -->
<!-- <bean id="userService" class="com.xhx.service.impl.UserServiceImpl">
<!--注入一个的对象类型 -->
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
<!-- 注入一个普通的字符串的值 -->
<constructor-arg name="username" value="构造器注入"></constructor-arg>
</bean> -->
<!--P名称空间注入:先在xmlns中引入 spring2.5以上版本 -->
<!-- <bean id="userService" class="com.xhx.service.impl.UserServiceImpl"
p:userDao-ref="userDao" p:username="p名称空间引入"></bean> -->
<!--spel注入 -->
<bean id="userService" class="com.xhx.service.impl.UserServiceImpl">
<property name="userDao" value="#{userDao}"></property>
<property name="username" value="#{userService.getUsername()}"></property>
<!-- 普通属性: p:属性名称= value;
对象属性: p:属性名称-ref= value; 属性名称必须提供set get方法。 -->
</bean>
(4)使用注解方式
普通属性:@Value
对象属性:
@Resource(name=“userService”)–实现依赖注入先按照name加type的方式检索;其次缺失name或者确实type只按照一项进行检索;其次name和type都省略,那么默认还是按照name检索
@Autowired—自动装配,此注解实现的自动装配是按照类实现注入,如果出现同名的类,那么此注解方式就不能识别是哪个类实现注入,此时会出现异常;如果为了避免出现异常,可以采用@Qualifier(value=“xx”)实现辅助,即Qualifier可以指明对象id
==Xml和注解方式比较 ==
注解:
优点: 方便开发:
弊端: 不利于维护,不能应用在任何的场景。 JDK或者是框架提供好的类,不能使用注解。只能使用在自定义的类上。
Xml方式:
优点: Xml的方法, 结构清晰,便于维护。 应用在任何的场景:
弊端: 开发复杂。步骤繁琐、
总结: 在实际开发过程当中, 可以采用xml, 可以采用XML。 还有一种, XML方法和注解式混合开发。 (各需所长)
Xml: 创建 对象
注解: DI属性注入
(4)AOP
定义:Aspect Oriented Programming,面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。Spring 引用了AspectJ 对AOP进行了一个很好的实现。
专业术语:
(一个博主的讲解)https://blog.csdn.net/qq_32317661/article/details/82878679
连接点: (join point) 可以被拦截到的点就是连接点。
以上接口当中的四个方法都有机会被功能性的增强, 这样的方法就是连接点。
切入点: (point Cut) 真正被拦截到的点就是切入点:
真正被增强的方法就是切入点。 在实际开发当中saveUser方法被功能性的增强 , 此时该方法就是一个切入点。
通知: (advice) 增强 (方法层面的增强)
在执行saveUser方法 之前我们可以对其进行一个权限的校验, checkPri(), 此时增强的这个部分内容就是通知。 也称之为增强。
引介: 在类层面进行一个增强。
目标: (target) 被增强的对象就是目标: (代理类)
织入: (Weaving) 将通知advice 应用在切点上(PonitCut)上的过程 就是织入
代理对象: (Proxy) 目标对象被增强后,就是一个代理对象。
切面; (aspect) 多个通知和多个切点的集合。