Spring基础
Spring 基础
spring概述
Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。
- 目的:解决企业应用开发的复杂性
- 功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
- 范围:任何Java应用
具体好处
- 降低组件直接的耦合度,实现软件各层之间的解耦
- 提供的众多服务(事务管理服务、消息服务)
Spring 集成
核心理念: IoC inversion of control 控制反转 / DI dependency injection 依赖注入
控制权从调用的类转换到spring容器,由spring来实例化对象及依赖注入
IOC 容器 优势与实现:
优势: 解偶 降低耦合度 提高代码 的灵活性 和维护性
实现: xml解析 反射创建实例 + 递归
技术 | 功能 |
---|---|
Spring-beans | ioc 的实现 配置文件的访问 创建管理 |
spring-core | 核心包 |
spring-context | 封装ioc 容器提供扩展功能 |
SpEL | Spring 表达式支持 |
基础服务 | |
---|---|
AOP | 面向切面编程 |
Aspects | 对Aspect 的支持 |
Instrumentation | 字节码操作 |
messaging | 对消息服务的支持 |
功能 | |
---|---|
transactions | 事务支持 |
JDBC | Spring 对JDBC 的支持 |
ORM | Spring 对于ORM 框架的支持 |
web | 对于web 开发的支持 |
属性配置
- value 注入基本类型
- ref 注入已有的bean
- List \ Set \ Map
1) 创建对象 2)依赖注入 ( 为属性填入实例)
<beans ...>
<bean id="userDAO" class="com.liuliu.spring.dao.UserDAOImpl"/>
<bean id="userService" class="...UserServiceImpl">
<property name="userDAO" ref="userDAO" />
<porperty name="age" value="18"/>
<property name="aList">
<list>
<value></value>
<bean></bean>
<ref></ref>
</list>
</property>
<property name="map">
<map>
<entry key="" value=""/>
....
</map>
</property>
</bean>
<!-- 实现了FactoryBean接口,那么这个bean的类型就是car类型,getObject方法的返回值 -->
<bean id="car" class="xxxx.CarFactoryBean"/>
</beans>
bean的实例化
- 默认构造器实例化
- 静态工厂方法实例化
<!-- 默认构造器实例化 -->
-<bean id="carFactory" class="xxxx.CarFactoryBean"/>
<!--静态工厂实例化 -->
<bean id="connection" class="xxx.JDBCUtil" factory-method="getConnection"/>
<!-- 实例工厂实例化 -->
<bean id="carFactoryBean" class="xxx.CarFactoryBean">
<bean id="car" factory-bean="carFactoryBean" factory-method="create"/>
<!--spring的FactoryBean接口 实现接口, 重写getObject和getObjectType -->
<bean id="car" class="xxxx.CarFactoryBean"/>
依赖注入的方式
- setter注入 必须提供setter方法
private Metal metal;
// 设值注入所需的setter方法
public void setMetal(Metal metal)
{this.metal=metal;}
xml 配置
<bean id="person" class="impl.handle.Person">
<!-- name 属性名 ref 注入的bean -->
<property name="metal" ref="steal"/>
</bean>
<bean id="steal" class="impl.handle.Steal"/>
- 构造器注入 有参构造
xml 配置private Metal metal; // 构造注入的构造函数 public Person(Metal metal,Axe axe) { this.metal=metal; }
<bean id="person" class="impl.handle.Person">
<constructor-arg name="参数名字" index=“ ” ref="steal(引用的bean)"/>
</bean>
<bean id="steal" class="impl.handle.Steal"/>
bean的作用域 默认单例
scope=""
- prototype 原型 => 每次创建一个实例
- [*]singleton 单例 => 一个bean的定义,只有一个实例,不是一个类只有一个实例
- request 一个请求一个实例
- session 一个会话一个实例
- websocket 一次websocket链接一个实例
生命周期
- 初始化和销毁
- 在bean声明上写init-method 和 destory-method
- 实现InitializingBean(初始化) 和DisposableBean(销毁)
- 在容器关闭的时候销毁
- bean: 实例化bean -> 依赖注入-> 处理各种借口 -> init -method -> 就绪 -> 调用destory() 方法-> 调用destory-method ->
核心API
- BeanFactory IOC容器的基本接口
- ApplicationContext 扩展的IOC容器
- ClassPathXmlApplicationContext 基于xml配置的IOC容器的实现类
- AnnotationConfigApplicationContext(AppConfig.class) 注解时IOC
IOC 配置方式
xml 配置
<!-- 静态工厂实例化-->
<bean id="util" scope="prototype" factory-method="getConnection" class="com.wo.liu.util.JDBC_util"></bean>
<!-- 实例化LoginDaoimp -->
<bean id="loginDao" class="com.wo.liu.dao.daoimp.LoginDaoimp">
</bean>
<!-- 实例化LoginServiceImp 加入依赖 -->
<bean id="LoginService" class="com.wo.liu.service.serviceImp.LoginServiceImp">
<property name="loginDao" ref="loginDao"/>
</bean>
Spring的注解+xml
- <context:component-scan base-package="${扫描的包路径}"/>
- 注解
- 声明SpringBean : @Controller(controller,控制器)
-
@Service (服务)
-
@Repository(DAO)
-
@Component(其他组件) <-> xml \<bean>
- 自动注入 : @Autowired value property constructor-arg
- @Scope 作用域
<!-- 自动扫包 --> <context:component-scan base-package="com.woniu" />
Java配置式的ioc
- @Bean @Configuration @ComponentScan
扫描:
@Configuration 标记为 配置类
@ComponentScan(“com.liuliu”)
扫描功能 并且指定扫描的包
等价<context:component-scan base-package=“com.woniu” /> - @PropertySource(“datebase.properties”)
- @Bean 标记依赖注入
- @PropertySource(“datebase.properties”)
- @ImportResource(“aop-config.xml”)
混合使用:
在注解类上可以用Import 导入配置,用ImportResource 导入xml
@Import(AppConfig.class)
@ImportResource("applicationContext.xml");
AOP
Aspect Oritented Programming AOP 面向切面编程
Object Oritented Programming oop 面向对象编程
业务功能:
系统功能:
公共的,在很多地方都会出现的功能,打印日志 性能监控 事务管理 安全验证
每一个类的每一个public 方法的参数都打印出来
把需要某一个系统功能的所有功能的方法看作一个切面
AOP 是Spring 一个重要的功能
名词
- 连接点 joinpoint 需要加入功能的位置(方法)
- 切入点 pointcut 执行加入功能的连接点,从连接点选出的需要加入功能的连接点
- 通知 advice 需要实现的功能
- 切面 aspect 切入点和通知的组合
- 目标对象target 连接点(方法)所在的对象
- 织入 weave 将切面应用到目标对象的过程
概念:
具有横切性质的系统功能,例如:日志记录、性能统计、事务管理、安全检查等等。散布在系统的各个类中。需要一种机制能将这类功能自动加入到需要的位置中去。这种机制就是AOP。
示例
-
userService userServiceImpl
-
BeforeExecution 通知 implements MethodBeforeAdvice
-
配置 : 把什么样的功能加入到什么地方去 / 在什么位置做什么事
<!-- 目标对象 -->
<bean userService/>
<!-- 通知 -->
<bean beforeExecution/>
<!-- 切入点:选出连接点 -->
<bean id="pointcut" class="...JdkRegexpMethodPointcut">
<property name="pattern" value="...userService.addUser"/>
</bean>
<!-- 切面 -->
<bean id="aspect" class="...DefaultPointcutAdvisor">
<property name="pointcut" ref="pointcut"/>
<property name="advice" ref="beforeExecution"/>
</bean>
<!-- 包装目标对象 -->
<bean class="...DefaultAdvisorAutoProxyCreator"/>
通知类型
- 前置通知 : 方法执行之前 MethodBeforeAdvice
- 后置通知 : 方法执行之后 AfterReturningAdvice
- 环绕通知 : 方法执行前后 MethodInterceptor
- 异常通知 : 抛出异常时
- 最终通知 : finally执行时
面向接口编程 1)解耦,修改实现类 2)默认使用接口的方式生成代理
<!-- 添加依赖 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
xml 配置
<bean id="txAdvic2" class="com.woniu.aop.TransactionaroundAdvice"/>
<aop:config>
<!-- 切面 -->
<aop:aspect ref="txAdvic2">
<!--切入点-->
<aop:pointcut id="servicePointcut" expression="execution(* com..service.imp.*.*(..))"/>
<aop:around method="invoke" pointcut-ref="servicePointcut"/>
</aop:aspect>
</aop:config>
通知的参数
非环绕式 joinPoint
环绕式 ProceedingjoinPoint
注解式配置AOP :
@Aspect 切面
@PointCut 切入点
@Arround @Before @After @AfterReturning @AfterThrowing
@EnableAspectAutoProxy
@Component
@Aspect
puvlic class Aspect{
@Pointcut("execution(*com.liu.*.**(..)")
public void servicePointcut(){}
// @Arround @Before @After @AfterReturning
// @AfterThrowing
@Around("servicePointcut")
public Object invoke(ProceedingjoinPoint pjp){
Object[] args =pjp.getArgs()'
Object resoult =null;
try{
<!-- 开启事务-->
result = pjp.proceed(args);
<!-- 提交事务-->
}catch(Throwable throwable){
<!-- 回滚事务 -->
throwable.println();
}
}
<!-- 生成代理类-->
<context:component-scan base-package="com.aop"/>
<!-- 生成代理类-->
<aop:aspectj-autoproxy/>
上一篇: Unity安卓读写配置文件
下一篇: spring基础(IOC)