Spring,IOC、AOP、事务管理

Spring 有两个核心部分
IOC:控制反转,把创建对象过程交给 Spring 进行管理
Aop:面向切面,不修改源代码进行功能增强

IOC
主要目的,降低代码耦合度
IOC 思想基于 IOC 容器完成,IOC 容器底层就是对象工厂
Spring 提供 IOC 容器实现两种方式:(两个接口)
(1)BeanFactory:IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用

  • 加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象

(2)ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人
员进行使用

  • 加载配置文件时候就会把在配置文件对象进行创建

ApplicationContext 接口有实现类

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">

原理
xml解析获取class路径 classvalue;
工厂模式;
通过Class.forname(classvalue).newInstance()反射创建对象

DI:依赖注入,就是注入属性,有多种方法,基于set,基于构造方法,P命名。

<!--1 service 和 dao 对象创建--> 
<bean id="userService" class="com.kk.service.UserService">
 <!--注入 userDao 对象
 name 属性:类里面属性名称
 ref 属性:创建 userDao 对象 bean 标签 id 值
 -->
 <property name="userDao" ref="userDaoImpl"></property>
</bean> 
<bean id="userDaoImpl" class="com.kk.dao.UserDaoImpl"></bean>

IOC bean 作用域
默认情况下,bean 是单实例对象,可以通过 bean 标签里面的属性scope用于设置单实例还是多实例
默认值,singleton,单实例对象
第二个值 prototype,多实例对象
bean 生命周期
(1)通过构造器创建 bean 实例(无参数构造)
(2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
(3)把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization (4)调用 bean 的初始化的方法(需要进行配置初始化的方法)
(5)把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization
(6)bean 可以使用了(对象获取到了)
(7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
可以通过 implements BeanPostProcessor类,重写前后置方法

spring,完全注解开发,其实在springboot中用的比较多

创建配置类,替代 xml 配置文件
//作为配置类,替代 xml 配置文件
@Configuration 
//替代开启扫描配置
@ComponentScan(basePackages = {"com.kk"})
public class SpringConfig {
}

注入bean
@Service
public class UserService {
 //@Autowired 根据属性类型进行自动装配,实际开发中基本用这个
 @Autowired 
 private UserDao userDao;

//@Qualifier:根据名称进行注入,@Qualifier 注解的使用,和上面@Autowired 一起使用

@Autowired //根据类型进行注入
@Qualifier(value = "userDaoImpl1") //根据名称进行注入
private UserDao userDao;3@Resource:可以根据类型注入,可以根据名称注入

//@Resource //根据类型进行注入
@Resource(name = "userDaoImpl1") //根据名称进行注入
private UserDao userDao;

//@Value:注入普通类型属性
@Value(value = "abc")
private String name;

AOP
主要应用,不修改源代码,在代码里添加新功能,比如权限管理,日志,查询数据库前进行数据源的切换;
原理
AOP 底层使用动态代理
1,有接口情况,使用 JDK 动态代理, 创建接口实现类代理对象,增强类的方法
2,没有接口情况,使用 CGLIB 动态代理,创建子类的代理对象,增强类的方法

在反射那个模块写了两种类型的实现方式
JDK,CGLIB实现方式

Spring 框架一般都是基于 AspectJ 实现 AOP 操作
AspectJ 表达式
(1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强
(2)语法结构: execution([权限修饰符] [返回类型] [类全路径] [方法名称] ([参数列表]) )
例 1:对 com.kk.service.UserService 类里面的 findAllUsers进行增强
execution(* com.kk.service.UserService.findAllUsers(…))
例 2:对 com.kk.service.UserService 类里面的所有的方法进行增强
execution(* com.kk.service.UserService.* (…))
例 3:对 com.kk.service包里面所有类,类里面所有方法进行增强
execution(*com.kk.service . * . * (…))

代码示例
先在配置文件开启AOP,或者完全注解,在配置类上开启

 <!-- 开启 Aspect 生成代理对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

@Configuration 
//替代开启扫描配置
@ComponentScan(basePackages = {"com.kk"})
//AOP代理开启
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class SpringConfig {
}

然后创建方法增强类

@Component
@Aspect
public class UserServiceProxy {
    @Before(value = "execution(* com.kk.service.UserService.saveUser2(..))")
    public void before() {
        System.out.println("before..................................................................");
    }
    @AfterReturning(value = "execution(* com.kk.service.UserService.saveUser2(..))")
    public void afterReturning() {
        System.out.println("afterReturning...................................................");
    }
    //最终通知
    @After(value = "execution(* com.kk.service.UserService.saveUser2(..))")
    public void after() {
        System.out.println("after......................................");
    }
    //异常通知
    @AfterThrowing(value = "execution(* com.kk.service.UserService.saveUser2(..))")
    public void afterThrowing() {
        System.out.println("afterThrowing.........");
    }
    //环绕通知
    @Around(value = "execution(* com.kk.service.UserService.saveUser2(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws
            Throwable {
        System.out.println("环绕之前.........");
        //被增强的方法执行
        proceedingJoinPoint.proceed();
        System.out.println("环绕之后.........");
    }
}

执行顺序,可以看下结果

环绕之前.........
before..................................................................
17:00:17,587 DEBUG SqlSessionUtils:97 - Creating a new SqlSession
17:00:17,593 DEBUG SqlSessionUtils:128 - Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4d9ac0b4]
17:00:17,603 DEBUG SpringManagedTransaction:87 - JDBC Connection [com.mysql.jdbc.JDBC4Connection@7241a47d] will be managed by Spring
17:00:17,608 DEBUG saveUser:159 - ==>  Preparing: INSERT INTO `kkkk`.`users` (`id`, `age`, `name`, `birthday`, `salary`) VALUES ( ?, ?, ?, '1991-02-28', '99999') 
17:00:17,644 DEBUG saveUser:159 - ==> Parameters: null, null, xxxxxx(String)
17:00:17,646 DEBUG saveUser:159 - <==    Updates: 1
17:00:17,647 DEBUG SqlSessionUtils:186 - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4d9ac0b4]
环绕之后.........
after......................................
afterReturning...................................................

如果有多个增强类多同一个方法进行增强,设置增强类优先级,在增强类上面添加注解 @Order(数字类型值),数字类型值越小优先级越高

@Component
@Aspect
@Order(1)
public class UserServiceProxy 

JdbcTemplate
Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作
使用:
在配置文件中创建相应的bean,注入dataSource即可,然后持久层Autowired创建即可;

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
 <!--注入 dataSource-->
 <property name="dataSource" ref="dataSource"></property>
</bean>

Spring 事务管理方面
SSM里面已经有xml配置版了,可以去那里看,这里再说下注解版:

<!--开启事务注解-->
 <tx:annotation-driven transactionmanager="transactionManager">
</tx:annotation-driven>
或者完全注解,在配置文件开启

@Configuration 
//替代开启扫描配置
@ComponentScan(basePackages = {"com.kk"})
//AOP代理开启
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableTransactionManagement
public class SpringConfig {
}

在 service 类上面(或者 service 类里面方法上面)添加事务注解
(1)@Transactional,这个注解添加到类上面,也可以添加方法上面
(2)如果把这个注解添加类上面,这个类里面所有的方法都添加事务
(3)如果把这个注解添加方法上面,为这个方法添加事务

@Service
@Transactional(propagation = Propagation.REQUIRED,isolation =Isolation.REPEATABLE_READ)
public class UserService {

这个注解里面可以配置事务相关参数,例上面的REQUIRED

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值