Spring基础IOC,AOP和事务

本文详细介绍了Spring框架中的核心概念,包括IOC(控制反转)的概念和过程,如BeanFactory和ApplicationContext,以及基于XML和注解的Bean管理。接着讲解了AOP(面向切面编程),包括代理情况、术语和实际操作。此外,还涵盖了JdbcTemplate的基本概念和Spring的事务管理,包括事务操作和配置参数。
摘要由CSDN通过智能技术生成

Spring

IOC

IOC 概念

对象创建交给spring,降低耦合度。

类之间相互依赖,如果某个类路径变化,另一个类也会受影响,所以IOC能降低耦合。

IOC 过程

通过xml解析,工厂模式,发射创建对象

  • xml 配置

    <bean id="dao" class="com.xxx.spring.UserDao"/>
    
  • 有service类和dao类,创建工厂类

    class UserFactory {
      public static UserDao getDao() {
        String classValue = class 属性值;
        Class clazz = Class.forName(classValue); //通过反射创建对象
        return (UserDao) clazz.newInstance();
      }
    }
    

IOC 接口

Spring提供了IOC容器两种实现方式 两个接口:都可以加在配置文件

  • BeanFactory:spring内部使用接口,一般开发不用,加载配置文件的时候不会创建对象,使用的时候才会创建对象。
  • ApplicationContext:BeanFactory接口的子接口,提供更多更强大功能。加载配置文件的时候就创建好了对象。
BeanFactory
  • ConfigurableApplicationContext

具体实现类:

  • XmlBeanFactory
ApplicationContext

有两个主要的实现类:

  • FileSystemXmlApplicationContext
  • ClassPathXmlApplicationContext

IOC 操作 Bean 管理

Bean管理指的是:创建对象 和 注入属性

基于xml配置
<bean id="dao" class="com.xxx.spring.UserDao"/>
  • id : 名称
  • class : 类名
  • name : 和id差不多,name中可以添加特殊符号

创建对象默认执行无参数构造方法

DI:依赖注入,就是注入属性,需要在创建对象基础上进行。

  • set方法注入:(需要有有参构造函数)

    <bean id="user" class="com.xxx.spring.bean.User">
        <property name="name" value="set"/>
    </bean>
    
  • 接口注入:有参构造函数 (需要注掉无参构造函数)

    <bean id="user" class="com.xxx.spring.bean.User">
        <constructor-arg name="name" value="args-construct"></constructor-arg>
    </bean>
    
  • 传入null

    <bean id="user" class="com.xxx.spring.bean.User" >
            <property name="name">
                <null/>
            </property>
        </bean>
    
  • 包含特殊符号

    <![CDATA[]]
    
  • 集合 数组 map

    <property name="name">
                <list>
                    <value></value>
                    <value></value>
                </list>
      					<map>
                    <entry key="" value=""></entry>
                </map>
            </property>
    
基于注解
  • @Component
  • @Service
  • @Controller
  • @Repository:一般用在Dao层

功能是一样的,都能创建bean实例

  1. 倒入spring-aop包

  2. 开启spring扫描

    xmlns:context="http://www.springframework.org/schema/context"
    
    <context:component-scan base-package="com.xxx.spring"/>
    
  3. 添加注解

    只扫描特定的组件,这里只扫描Component组件

    <context:component-scan base-package="com.xxx.spring">
            <context:include-filter type="annotation" 
                                    expression="org.springframework.stereotype.Component"/>
        </context:component-scan>
    

属性注入:

  • @AutoWired:根据属性类型自动装配

    @Qualifier@AutoWired一起使用
    
    @AutoWired
    private UserService userService;
    
    如果多个Service实现类UserService接口,那么使用Qulifier
    @AutoWired
    @Qualifier(value = "dao1") //根据名称进行注入
    private UserService userService;
    
  • @Qualifier:根据属性名称进行注入

  • @Resource:可以根据名称注入,也可以根据属性注入

    import javax.annotation.Resource
    
    @Resource(name = "dao1")
    
  • @Value : 注入普通类型属性

    @Value(value = "abc")
    private String name;  // name = "abc";
    
p名称空间注入
xmlns:p="http://www.springframework.org/schema/p"

<bean id="user" class="com.xxx.spring.bean.User" p:name="p namespace"/>

IOC Bean 管理

Spring 有两种bean,普通bean和工厂bean

  • 普通bean:就是平时创建的bean
  • 工厂bean:在配置文件定义bean类型可以和返回类型不一样
  1. 创建类,实现接口 FactoryBean
  2. 实现接口的方法,在实现的方法中定义返回的bean类型

IOC Bean 作用域

  • 单例模式:单例的情况下,spring容器启动的时候就会创建bean
  • 多例模式:spring容器启动的时候先不创建bean

IOC Bean 生命周期

概念:

从对象创建到销毁的过程

  1. 通过构造器创建bean实例
  2. 为bean属性设置值和对其他bean的引用
  3. 把bean实例传给bean的后置处理器的方法
  4. 初始化bean的方法(需要进行配置)
  5. 把bean实例传递给bean后置处理器
  6. bean可以使用
  7. 容器关闭的时候,调用bean销毁的方法(需要进行配置销毁方法)
演示:
<bean id="myBean" class="com.xxx.spring.bean.Test" init-method="init" destroy-method="destory">
        <property name="name" value="life-cycle" />
    </bean>
public class Test {

    private String name;

    Test() { System.out.println("non args construction function"); }

    public void setName(String name) {
        System.out.println("using set function");
        this.name = name; }

    public String getName() { return name; }

    public void init() { System.out.println("init......"); }

    public void destory() { System.out.println("destroying .... "); }
}

后置处理器
public class MyPostBean implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("post before init");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("post after init");
        return bean;
    }

}

<bean id="myBeanPost" class="com.xxx.spring.bean.MyPostBean"></bean>

会自动处理该xml定义的bean

自动装配

@Autowire 属性两个常用值, “byName” : 名字一一对应。 “byType”:根据类型自动注入

外部配置

<context:property-placeholder location="classpath:jdbc.properties"/>

完全注解开发

  1. 创建配置类

    @Configuration
    @ComponentScan(basePackages = "com.xxx.spring")
    public class SpringConfig {
    }
    
  2. 测试代码

    ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    
            UserS test = context.getBean("a", UserS.class);
    

AOP

概念

Aspect-Oriented Programming:面向切面编程,降低程序耦合度。不通过修改代码就能修改业务逻辑。

AOP代理情况

  • 有接口使用JDK代理:创建接口实现类的代理对象,增强类中的方法
  • 无接口使用cglib代理:创建当前类子类的代理对象,增强方法

Spring 动态代理

调用 Object 的newProxyInstance

  • 参数1 类加载器
  • 参数2 接口
  • 参数3 InvocationHandler

AOP 术语

  • 连接点:能被增强的方法
  • 切入点:实际真正被增强的方法
  • 通知(增强):
    1. 实际增强的逻辑部分称为通知(增强)
    2. 通知类型:
      • 前置通知 @Before
      • 后置通知 @After
      • 环绕通知 @Around
      • 异常通知 @AfterThrowing
      • 最终通知 @AfterReturning
  • 切面:是动作,把通知应用到切入点称为切面

AOP 操作

  1. AspectJ 使用

  2. 切入点表达式:

    execution([权限修饰符,*][返回类型][类全路径][方法名称]([参数列表]))
    
@Around(value = "execution(* com.xxx.spring.aop.MyImpl.myFun(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("around before");
        proceedingJoinPoint.proceed();
        System.out.println("around after");
    }

环绕在函数执行前后都执行,中间需要proceed()函数来区分。

运行顺序区分:

try{
    try{
        //@Before
        method.invoke(..);
    }finally{
        //@After
    }
    //@AfterReturning
}catch(){
    //@AfterThrowing
}

提取相同切入点

//提取相同切入点
    @Pointcut(value = "execution(* com.xxx.spring.aop.MyImpl.myFun(..))")
    public void pointDemo() {}
@Component
// 同一个类的不同增强类,数字越小优先级越高,优先执行
@Order(value = 1)
@Aspect

完全注解开发

@Configuration
@ComponentScan(basePackages = "com.xxx.spring")
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class SpringConfig {
}

JdbcTemplate

概念

Spring对Jdbc进行封装,方便对数据库操作

@Autowired
private JdbcTemplate jdbcTemplate;
        String sql = "insert into book values(?,?)";
        String[] args = {"a", "b"};
        int result = jdbcTemplate.update(sql, args);

查询数量

jdbcTemplate.queryForObject(sql, Integer.class);

查询返回对象

jdbcTemplate.queryForObject(String sql, RowMapper<T> rowMapper, Object... args)
// 实际使用 BeanPropertyRowMapper
// new BeanPropertyRowMapper<Book>(Book.class)

查询返回对象集合,使用 query 方法

批量操作:

jdbcTemplate.batchUpdate(String sql, List<Object[]> batchArgs)

事务

概念

事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,要么都失败。

ACID

  • 原子性
  • 一致性
  • 隔离性
  • 持久性
try {
  // 开启事务
  
  //出现异常
  
  //没出现异常,提交事务
} catch (Exception e) {
  // 回滚异常
}

Spring事务管理操作

一般事务加在 Service 层,业务逻辑层

  • 编程式事务管理

    例如上述的代码操作()

  • 声明式事务管理

    1. 基于注解
    2. 基于xml配置文件

Spring声明式事务管理,底层使用了AOP

Spring事务管理API

  1. 提供了一个接口,代表事务管理器,这个接口针对不同的框架提供了不同的实现类

    /**
     * This is the central interface in Spring's transaction infrastructure.
     * Applications can use this directly, but it is not primarily meant as API:
     * Typically, applications will work with either TransactionTemplate or
     * declarative transaction demarcation through AOP.
     *
     * <p>For implementors, it is recommended to derive from the provided
     * {@link org.springframework.transaction.support.AbstractPlatformTransactionManager}
     * class, which pre-implements the defined propagation behavior and takes care
     * of transaction synchronization handling. Subclasses have to implement
     * template methods for specific states of the underlying transaction,
     * for example: begin, suspend, resume, commit.
     *
     * <p>The default implementations of this strategy interface are
     * {@link org.springframework.transaction.jta.JtaTransactionManager} and
     * {@link org.springframework.jdbc.datasource.DataSourceTransactionManager},
     * which can serve as an implementation guide for other transaction strategies.
     *
     * @author Rod Johnson
     * @author Juergen Hoeller
     * @since 16.05.2003
     * @see org.springframework.transaction.support.TransactionTemplate
     * @see org.springframework.transaction.interceptor.TransactionInterceptor
     */
    public interface PlatformTransactionManager extends TransactionManager {
    
    	/**
    	 * Return a currently active transaction or create a new one, according to
    	 * the specified propagation behavior.
    	 * <p>Note that parameters like isolation level or timeout will only be applied
    	 * to new transactions, and thus be ignored when participating in active ones.
    	 * <p>Furthermore, not all transaction definition settings will be supported
    	 * by every transaction manager: A proper transaction manager implementation
    	 * should throw an exception when unsupported settings are encountered.
    	 * <p>An exception to the above rule is the read-only flag, which should be
    	 * ignored if no explicit read-only mode is supported. Essentially, the
    	 * read-only flag is just a hint for potential optimization.
    	 * @param definition the TransactionDefinition instance (can be {@code null} for defaults),
    	 * describing propagation behavior, isolation level, timeout etc.
    	 * @return transaction status object representing the new or current transaction
    	 * @throws TransactionException in case of lookup, creation, or system errors
    	 * @throws IllegalTransactionStateException if the given transaction definition
    	 * cannot be executed (for example, if a currently active transaction is in
    	 * conflict with the specified propagation behavior)
    	 * @see TransactionDefinition#getPropagationBehavior
    	 * @see TransactionDefinition#getIsolationLevel
    	 * @see TransactionDefinition#getTimeout
    	 * @see TransactionDefinition#isReadOnly
    	 */
    	TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
    			throws TransactionException;
    
    	/**
    	 * Commit the given transaction, with regard to its status. If the transaction
    	 * has been marked rollback-only programmatically, perform a rollback.
    	 * <p>If the transaction wasn't a new one, omit the commit for proper
    	 * participation in the surrounding transaction. If a previous transaction
    	 * has been suspended to be able to create a new one, resume the previous
    	 * transaction after committing the new one.
    	 * <p>Note that when the commit call completes, no matter if normally or
    	 * throwing an exception, the transaction must be fully completed and
    	 * cleaned up. No rollback call should be expected in such a case.
    	 * <p>If this method throws an exception other than a TransactionException,
    	 * then some before-commit error caused the commit attempt to fail. For
    	 * example, an O/R Mapping tool might have tried to flush changes to the
    	 * database right before commit, with the resulting DataAccessException
    	 * causing the transaction to fail. The original exception will be
    	 * propagated to the caller of this commit method in such a case.
    	 * @param status object returned by the {@code getTransaction} method
    	 * @throws UnexpectedRollbackException in case of an unexpected rollback
    	 * that the transaction coordinator initiated
    	 * @throws HeuristicCompletionException in case of a transaction failure
    	 * caused by a heuristic decision on the side of the transaction coordinator
    	 * @throws TransactionSystemException in case of commit or system errors
    	 * (typically caused by fundamental resource failures)
    	 * @throws IllegalTransactionStateException if the given transaction
    	 * is already completed (that is, committed or rolled back)
    	 * @see TransactionStatus#setRollbackOnly
    	 */
    	void commit(TransactionStatus status) throws TransactionException;
    
    	/**
    	 * Perform a rollback of the given transaction.
    	 * <p>If the transaction wasn't a new one, just set it rollback-only for proper
    	 * participation in the surrounding transaction. If a previous transaction
    	 * has been suspended to be able to create a new one, resume the previous
    	 * transaction after rolling back the new one.
    	 * <p><b>Do not call rollback on a transaction if commit threw an exception.</b>
    	 * The transaction will already have been completed and cleaned up when commit
    	 * returns, even in case of a commit exception. Consequently, a rollback call
    	 * after commit failure will lead to an IllegalTransactionStateException.
    	 * @param status object returned by the {@code getTransaction} method
    	 * @throws TransactionSystemException in case of rollback or system errors
    	 * (typically caused by fundamental resource failures)
    	 * @throws IllegalTransactionStateException if the given transaction
    	 * is already completed (that is, committed or rolled back)
    	 */
    	void rollback(TransactionStatus status) throws TransactionException;
    
    }
    
    

事务操作

  1. spring配置事务管理器

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource";
        </bean>
    
  2. 开启事务注解

     xmlns:tx="http://www.springframework.org/schema/tx"
           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/tx
            http://www.springframework.org/schema/tx/spring-tx.xsd
    
    <!-- 开启事务注解,指定事务管理器 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
  3. 在Service类或方法上面添加事务注解

事务配置参数

  • propagation:事务传播行为

    https://i-blog.csdnimg.cn/blog_migrate/bbc6c247b93791b5b9d252715d3b544e.png

  • isolation:隔离级别

    多事务操作之间可能会影响

    1. 脏读:一个未提交事务读到另一个未提交事务的数据 (读未提交)
    2. 不可重复读:一个未提交事务读到另一个提交事务的数据 (读已提交)
    3. 幻读:一个未提交事务读到另一个提交事务添加数据 (可重复读)
  • timeout:超时时间

  • readOnly:是否只读

  • rollbackFor:回滚

  • noRollbackFor:不回滚

    指定哪些异常不回滚

完全注解开发

package com.xxx.spring;

@Configuration
@ComponentScan(basePackages = "com.xxx.spring")
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableTransactionManagement //开启事务
public class SpringConfig {

    // 创建数据库连接池
    @Bean
    public DruidDataSource getDruidDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://192.168.157.2:3306/mq");
        dataSource.setUsername("admin");
        dataSource.setPassword("admin");
        return dataSource;
    }

    // 创建jdbcTemplate
    @Bean
    public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
        // 从IOC容器中根据类型找到 datasource
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }

    // 创建事务管理器对象
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource  dataSource) {
        DataSourceTransactionManager transactionManager =
                new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值