一:SpringIoc原理:
1,IOC:控制反转,是spring的核心,是指把bean与bean之间的关系交给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)切入点:执行目标的对象,即被拦截添加功能的对象。
3:AOP原理:
使用代理模式
代理:
静态代理:需要生产代理对象,不推荐使用
动态代理:不需要生产代理对象,推荐使用。
动态代理:
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();
}
}