手写spring事物

一:SpringIoc原理:

1,IOC:控制反转,是spring的核心,是指把beanbean之间的关系交给spring来处理,由spring来管理对象的生命周期和关系。

2,DI:依赖注入:是指A需要操作数据库的时候自己写代码会创建Connection对象,但是有了spring之后A只需要告诉spring我需要一个connecion对象,这时spring会创建一个Connection对象注入到A对象中来完成对各个对象之间关系的控制,spring就是通过反射来进行动态生成对象,执行对象方法,改变对象属性,来进行注入的。

3,依赖注入的思想也很简单,它是通过反射机制实现的,在实例化一个类时,它通过反射调用类中set方法将事先保存在HashMap中的类属性注入到类中

4,https://blog.csdn.net/jiangyu1013/article/details/72654373  链接查看

二:SpringAop原理:

1,什么是Aop技术:

面向切面编程,解决代码复用,核心点就是在方法之前或之后处理一些事情

2,哪些场景应用到Aop

日志打印,权限控制,事物管理,参数验证,性能监控,异常处理。

2,AOP技术:

(1)关注点:重复的代码,比如好多地方需要添加日志。

(2)切面:重复代码形成的类,也叫做切面类,在运行的业务方法上动态植入。

(3)切入点:执行目标的对象,即被拦截添加功能的对象。

3AOP原理:

使用代理模式

代理:

静态代理:需要生产代理对象,不推荐使用

动态代理:不需要生产代理对象,推荐使用。

动态代理:

jdk代理模式:需要接口实现,基于反射虚拟生成代理类。

Cglib代理模式:需要子类实现,基于ASM字节码虚拟生成代理类,效率比jdk代理要高。

静态代理代码实现:

(1)目标对象:

public class UserServiceImpl {

public void add(){

System.out.println("数据库添加一条数据.....");

}

}

(2)代理对象:

public class UserServiceProxy {

 

private UserServiceImpl userServiceImpl;

//有参构造函数

 public UserServiceProxy(UserServiceImpl userServiceImpl){  

this.userServiceImpl = userServiceImpl;

}  

 public void add(){

 System.out.println("静态代理对象开启...");

 userServiceImpl.add();

 System.out.println("静态代理对象关闭...");

 }

}

 

(3)测试方法:

public class ProxyTest {

public static void main(String[] args) {

UserServiceImpl userServiceImpl = new UserServiceImpl();

UserServiceProxy userServiceProxy = new UserServiceProxy(userServiceImpl);

userServiceProxy.add();

}

}

 

4,spring事物:

(1)编程事物:手动事物,手动开启,手动提交

(2)声明事物:自动事物,有注解和扫包(配置xml)两个版本。原理是编程事物+反射机制包装起来的。

(3)使用声明事物注意的要点:

事物是程序运行如果没有错误会自动提交事物,发生异常时会自动回滚,如果代码中用到了try了,则要在catch中手动回滚,手动回滚代码是:

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

5,spring物注解:

(1)自定义事物注解

(2)手写封装spring事物

(3)具体扫包(定义一个事物扫包Aop,具体拦截哪些方法)

(4)拦截方法的时候使用反射技术判断该方法上是否存在事物注解,如果存在则开启事物,不存在就不开启事物。

(5)引入spring aop的依赖和编写spring.xml

代码实现:

(1):/**1,定义事物注解

* @ClassName: WjcTransation

* @date 2018年6月7日 上午9:03:52

* @author:[王池]

 */

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface WjcTransation {}

(2):
/**
 * 自定义事物注解具体实现
* @ClassName: AopWjcTransation
* @date 2018年6月7日 上午9:41:59
* @author:[王池]
 */
@Component
@Aspect
public class AopWjcTransation {

@Autowired
private TransactionUtils transactionUtils;
private TransactionStatus transactionStatus;
@Pointcut("execution(* com.spring.service.UserService.*(..))")
private void advice() {}
//事物回滚
@AfterThrowing("advice()")
public void afterThrowing() throws NoSuchMethodException, SecurityException{
//获取当前事物自动回滚
//TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
  if(transactionStatus!=null){   
  transactionUtils.rollback();
  }  
}
//环绕通知
  @Around("advice()")
public void around(ProceedingJoinPoint pj) throws Throwable{
 Signature signature = pj.getSignature();    
 MethodSignature methodSignature = (MethodSignature)signature;    
 Method targetMethod1 = methodSignature.getMethod();
 System.out.println("targetMethod1 :"+targetMethod1);
   
     WjcTransation transation = getTargetMethod(pj); 
     //3,如果有注解开启事物
     if(transation!=null){        
      System.out.println("开启事物......");
      transactionStatus =transactionUtils.begin();
      }       
    //4,执行目标方法 
pj.proceed();//作用是让目标方法执行,环绕通知=前置通知+执行目标方法+后置通知,proceed()用于启动目标方法
//5,提交事物
if(transactionStatus!=null){
System.out.println("提交事物......");
transactionUtils.commite(transactionStatus);
}
}
 /**
  * 代码封装(获取方法上面是否有注解)
 * @author:王池
 * @param @param pj
 * @param @return
 * @param @throws NoSuchMethodException
 * @param @throws SecurityException    参数
 * @return Method    返回类型
 * @throws
  */
 public WjcTransation getTargetMethod(ProceedingJoinPoint pj) throws NoSuchMethodException, SecurityException{
 //1,获取目标对象方法
   //获取目标对象方法名称(add)
       String method = pj.getSignature().getName();
       MethodSignature msig= (MethodSignature) pj.getSignature();
       //获取目标对象的接口实现类
       Class<?> classTarget = pj.getTarget().getClass();
       //获取目标对象的类型
       Class<?>[] parameterTypes = msig.getParameterTypes();
       //获取目标对象接口实现类方法
       Method targetMethod = classTarget.getMethod(method, parameterTypes);
       //2,获取该方法上面的注解
   WjcTransation transation = targetMethod.getDeclaredAnnotation(WjcTransation.class);
       return transation;
 }
}
(3):写dao方法:和接口实现类
@Service
public class UserServiceImpl implements UserService{

@Autowired
private UserDao userDso;
@Autowired
private TransactionUtils transactionUtils;
@WjcTransation
public void add() {
userDso.addUser("王q", 20);
System.out.println("########");
int a = 10/0;
userDso.addUser("王a", 21);
}

@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public void addUser(String name,Integer age){
String sql = "INSERT INTO t_user (name,age) VALUES ( ?, ?)";
int result = jdbcTemplate.update(sql, name,age);
System.out.println("result:"+result);
}
}
(4)写spring.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
      <!-- 扫包 -->
   <context:component-scan base-package="com.spring"></context:component-scan> 
   <!-- 开启事物注解 -->
   <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
   <!-- 1,配置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8">
</property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
</bean>
<!--2, jdbc模板 ,依赖数据源,注入dataSource-->
 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
         <property name="dataSource" ref="dataSource"></property>
      </bean>
 <!-- 3,事务核心管理器,封装了所有事务操作. 依赖于连接池 -->
    <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!--4, 开启使用注解管理aop事务 -->
   <!-- <tx:annotation-driven transaction-manager="transactionManager" />  --> 
</beans>

(5):写测试类:
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) applicationContext.getBean("userServiceImpl");
userService.add();
}
}

猜你喜欢

转载自blog.csdn.net/wjc2013481273/article/details/80813310
今日推荐