初学Spring
Spring
Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。Spring框架可以类与类之间的耦合度降低,使代码的可维护性大大提升,让类与类之间的关系更加灵活。
IoC
spring-bean:IoC实现,配置文件的访、创建和管理
- spring-code:核心工具包
- spring-Context:封装IoC容器,提供扩展功能
- SqEL:spring的表达式支持
基础服务
- AOP:面向切面编程支持
- spring-Aspects:对Aspects框架的支持
- instruction:字节码操作
- message:对消息服务的支持
功能
- transactions:事务支持
- JDBC:对JDBC的支持
- ORM:对ORM框架的支持
- web:对web开发的支持
Spring集成
核心理念:IOC(Inversion of Control ):控制翻转
DI(dependency injection):依赖注入
上边两个词的意思就是:将原来类与类之间相互的控制权转换到spring容器中,由spring容器来实例化对象以及依赖注入,由此可降低类之间的耦合度。
实现过程:创建对象 ---> 依赖注入(为属性填入实例)
配置方式
xml配置方式
-
属性配置
- value注入基本类型
- ref:注入已有bean
- 其他:List/Set/Map
-
Bean的实例化
- 默认构造器实例化
- 静态工厂实例化
##创建一个connection作为springbean <bean id="connection" factory-method="getConnection" class="com.danran···.JDBCUtils"/> ##类(JDBCUtils)的静态方法(getConnection),返回值作为bean
- 工厂bean实例化
##工厂bean <bean id="holidayFactory" class="com.woniuxy.spring.factory.HolidayFactory"/> ##holidayBean <bean id="holiday" factory-bean="holidayFactory" factory-method="create"></bean>
- spring的factorybean接口实例化
- 一个类实现FactoryBean接口,实现其方法
- 配置之后,bean的实例为FactoryBean#getObject方法的返回值
public class CarFactory implements FactoryBean<Car> { public Car getObject() throws Exception { return new Car(); } public Class<?> getObjectType() { return Car.class; } }
<bean id="car" class="com.woniuxy.spring.factory.CarFactory"/>
-
核心AIP
- BeanFactory IoC容器的基本接口
- ApplicationContext 可用的IoC容器接口
- ClassPathXmlApplicationContext xml配置文件的IoC容器的实现类
-
依赖注入
- setter注入
- 构造器注入
<constructor-arg name index> 设置vlaue ref list set
-
bean 的作用域
- prototype 原型 => 每次创建一个实例
- singleton 单例 => 一个bean的定义,只有一个实例,不是一个类只有一个实例
- request 一个请求一个实例
- session 一个会话一个实例
- websocket 一次websocket链接一个实例
-
bean的生命周期
- bean配置上写init-method和destory-method
- 实现initializingBean和SisposableBean及其方法
- 容器创建时创建
- 容器关闭时销毁
注解式 + xml 式IoC
注解替代xml配置文件
- 注解
- 注册springbean @Controller @Service @Repository @Component
- 自动依赖注入 @Autowired @Value
- 生命周期 @PostConstruct @PreDestroy
- 作用域范围 @Scope
- 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.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--指定扫描的范围,包括递归的所有的包和子类--> <context:component-scan base-package="com.woniuxy.spring"/> </beans>
java类纯注解式
- 标记配置类
@Configuration - 数据源配置文件
PropertySource(“配置文件路径”) - 声明Springbean
- @Bean
- 依赖注入需要
- 方法签名该依赖,由Spring容器自动注入该依赖
- 直接调用方法
- initMethod\destroyMethod
- 依赖注入需要
- @Scope
- @Bean
- 包扫描
- @ComponentScan
AOP
AOP(Aspect Oriented Programming):面向切面编程
OOP(Object Oritened Proguramming):面向对象编程
AOP是 OOP的 延续,也是Spring框架中一个重要的内容他更多的用于系统功能方面,多出现于一些公共的地方,比如:印日志、性能监控、事务管理、安全验证等这种会重复使用的代码,可以增加代码的复用性。
- 切面、连接点、切点
一捆面条,一刀切下去会出现一个切面
,这个切面的的所有面条我们可以把它看做是一个连连接点
,这些连接点中又有一些比较特别的,这些比较特别的我们将其看做切入点
,这些连接点就是我们要加入功能的地方
名称解释
- 连接点 JoinPoint 需要加入功能的位置,方法
- 切入点 PointCut 真正执行加入功能的连接点
- 通知 Advice 需要实现的功能
- 切面 Aspect Java语言中,将切入点和通知等组装在一起的代码单元
- 目标对象 Target 要操作的对象
- 织入 Weave 将功能加入到切入点中的过程
配置方式
xml配置
- 编写service类
- 编写通知,实现MethodBeforeAdvice接口
//method 要执行的方法 //args 方法的参数 //target 方法所在的对象 public void before(Method method,object[] args,Object terget) throws Throeable{ }
- xml配置
*配置目标对象
* 配置通知
* 配置切入点
class= org.springframework.aop.support.JdkRegexpMethodPointcut ,配置属性pattern=> service的方法
* 配置切面
class=org.springframework.aop.support.DefaultPointcutAdvisor 连接切入点和通知
* 包装目标对象类获取bean,调用方法,通知执行·····
class= org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator
具体代码如下:<?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="userService" class="com.woniuxy.spring.aop.service.impl.UserServiceImpl"/> <!--通知: 实现了打日志的功能(打印日志实现类)--> <bean id="beforeExecution" class="com.woniuxy.spring.aop.component.BeforeExecution"/> <!--切入点:选出了需要增加功能的方法--> <bean id="pointCut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"> <property name="pattern" value="com.woniuxy.spring.aop.service.impl.UserServiceImpl.addUser"/> </bean> <!--切面:连接切入点和通知,让打日志功能在切入点的位置执行--> <bean id="aspect" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="pointcut" ref="pointCut"/> <property name="advice" ref="beforeExecution"/> </bean> <!--包装userService--> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/> </beans>
通知类型
- 前置通知:方法执行之前执行
- 实现接口:MethodBeforeAdvice
- 后置通知:方法执行之后执行
- 实现接口:AfterReturningAdvice
- 环绕通知:方法执行前后执行
- 现接口:MethodInterceptor
- 异常通知:抛出异常时执行
- 实现接口: ThrowsAdvice
- 最终通知:finally执行时执行
事务
用到的jar包
aspectj
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
事务: 一批同时成功或者失败的DML
配置方式
xml
-
xml配置
<!--切面配置--> <aop:config> <aop:aspect ref="txAdvice"> <!--切入点--> <aop:pointcut id="servicePointcut" expression="execution(* com.woniuxy.spring.aop.service.impl.*.*(..))"/> <!--通知--> <!--前置--><aop:before method="begin" pointcut-ref="servicePointcut"/> <!--后置--><aop:after-returning method="commit" pointcut-ref="servicePointcut"/> <!--异常--><aop:after-throwing method="rollback" pointcut-ref="servicePointcut"/> </aop:aspect> </aop:config>
xml + 注解
- xml
<!--扫包--> <context:component-scan base-package="......" /> <!--自动生成代理--> <aop:aspectj-autoprexy />
- java 注解
- 加springbean注解(目标对象)
- 创建通知实现类(添加相应注解)
- Bean:@Component
- 切面:@Aspect
- 切入点:@Pointcut
- 通知类型:@Around @Befrore @After @AfterReturning @AfterThrowing
java注解式
将xml + 注解式中xml配置文件用一个java配置类替代,其他配置一样
新建一个java配置类,为其添加一下注解即可:
- 标记配置类:@Configuration
- 扫包:@Component(“包路径”)
- 自动生成代理类:@EnableaspectJAutoProoxy