SpringAOP.md

09 AOP

1、 面向切面编程

在软件业,AOP为aspect oriented programming 的缩写,面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,AOP是OOP的延续,是软件开发中的一个热点,也是spring 框架中的一个重要内容,是函数式编程的一种衍生, 利用AOP可以对业务逻辑的各个部分惊醒隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

AOP思想: 横向重复,纵向抽取

  1. 底层实现:

spring的 AOP 的底层用到两种代理机制:

JDK 的动态代理: 针对实现了接口的类产生代理

Cglib 的动态代理:针对没有实现接口的类产生代理,应用的是底层的字节啊增强的技术,生成当前类的子类对象

3.AOP 的开发中的相关术语

  • joinpoint 连接点,指那些被拦截到的点,在spring 中,这些点指的是方法,因为spring只支持方法类型的连接点
  • PointCut 切入点: 指我们要对哪些jointpoint 进行拦截的定义
  • advice 通知: 拦截到jointpoint之后要做的事情就是通知,通知分为前置通知,后置通知,异常通知,最终通知,环绕通知
  • introduction 引介: 一种特殊的通知在不修改类代码的前提下,introduction 可以在运行期为类动态地添加一些方法或Field
  • aspect 切面是切入点和通知的结合
  • target
  • proxy
  • weaving

插入在crud 中的事务处理代码就是切面

pointcut

public class UserServiceImpl implements UserService {

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

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

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

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

aspect

public class TransactionAdvice {
    public void before(){
        System.out.println("before");
    }

    public void after(){
        System.out.println("after,this will be used no matter there is exception or not");
    }

    public void afterReturning(){
        System.out.println("will not be used if there is exception");
    }

    public void afterException(){
        System.out.println("will be used if there is exception");
    }

    public Object around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("before");
        Object proceed = point.proceed();
        System.out.println("after");
        return proceed;


    }
}

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean name="userService" class="com.leiqingqi.aop.service.UserServiceImpl"/>

    <bean name="transactionAdvice" class="com.leiqingqi.aop.advice.TransactionAdvice"/>

    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* com.leiqingqi.aop.service..*ServiceImpl.*(..))"/>
        <aop:aspect ref="transactionAdvice">
            <aop:before method="before" pointcut-ref="pointcut"/>
            <aop:after method="after" pointcut-ref="pointcut"/>
            <aop:after-returning method="afterReturning" pointcut-ref="pointcut"/>
            <aop:after-throwing method="afterException" pointcut-ref="pointcut"/>
            <aop:around method="around" pointcut-ref="pointcut"/>
        </aop:aspect>
    </aop:config>

</beans>

test

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AOPTest {

    @Autowired
    private UserService userService;

    @Test
    public void testUpdate() {
        userService.update();
    }

    @Test
    public void testSave() {
        userService.save();
    }

}

10 AOP 注解开发

配置文件

    <bean name="userService" class="com.leiqingqi.aop.service.UserServiceImpl"/>

    <bean name="transactionAdvice" class="com.leiqingqi.aop.advice.TransactionAdvice"/>

   <aop:aspectj-autoproxy/>

注解:

@Aspect
public class TransactionAdvice {

    @Pointcut("execution(* com.leiqingqi.aop.service..*ServiceImpl.*(..))")
    public void pointcut(){}

    @Before("TransactionAdvice.pointcut()")
    public void before(){
        System.out.println("before");
    }

    @After("TransactionAdvice.pointcut()")
    public void after(){
        System.out.println("after,this will be used no matter there is exception or not");
    }

    @After("TransactionAdvice.pointcut()")
    public void afterReturning(){
        System.out.println("will not be used if there is exception");
    }

    @AfterThrowing("TransactionAdvice.pointcut()")
    public void afterException(){
        System.out.println("will be used if there is exception");
    }

    @Around("TransactionAdvice.pointcut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("before");
        Object proceed = point.proceed();
        System.out.println("after");
        return proceed;


    }
}

11 jdbcTemplate

导入jar包

spring-jdbc  mysql-connector-java  spring-tx   spring-context  mchange-commons-java  c3p0

一个工具类,使用c3p0 缓冲池

public class DataSourceUtil {

    public static JdbcTemplate getJdbcTemplate() throws PropertyVetoException {

        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/blog1701?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false");
        dataSource.setUser("root");
        dataSource.setPassword("12345");

        return new JdbcTemplate(dataSource);
    }
}

可以设置applicationContext.xml 文件

	<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource;">
        <property name="driverClass" value="${driver}"/>
        <property name="jdbcUrl" value="${url}"/>
        <property name="user" value="${username}"/>
        <property name="password" value="${password}"/>
    </bean>


    <bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate;">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean name="blogDao" class="com.leiqingqi.dao.BlogDaoImpl">
        <property name="jt" ref="jdbcTemplate"/>
    </bean>

11.1 save

public int save(Blog blog) {
    String sql = " insert into blog (title,author_id,state, featured, style) values (?,?,?,?,?)";
    return jt.update(sql, blog.getTitle(), blog.getAuthorId(), blog.getState(), blog.getFeatured(), blog.getStyle());

}

11.2 delete

public int delete(Integer id) {
    String sql = "delete from blog where id = ?";
    return jt.update(sql, id);

}

11.3 update

public int update(Blog blog) {
    String sql = "update blog set title = ?,author_id=?,state=?,featured=?,style=?";
    return jt.update(sql, blog.getTitle(), blog.getAuthorId(), blog.getState(), blog.getFeatured(), blog.getStyle());
}

11.4 getById

public Blog getById(Integer id) {
    String sql = "select * from blog where id = ?";

    return jt.queryForObject(sql, new RowMapper<Blog>() {
        public Blog mapRow(ResultSet resultSet, int index) throws SQLException {
            return mapBlogHandler(resultSet);
        }
    }, id);
}
public Blog mapBlogHandler(ResultSet resultSet) throws SQLException {
    Blog blog = new Blog();
    blog.setId(resultSet.getLong("id"));
    blog.setAuthorId(resultSet.getLong("author_id"));
    blog.setFeatured(resultSet.getLong("featured"));
    blog.setState(resultSet.getString("state"));
    blog.setStyle(resultSet.getString("style"));
    blog.setTitle(resultSet.getString("title"));

    return blog;
}

11.5 getAll

public List<Blog> getAll() {
    String sql = "select * from blog ";
    return jt.query(sql, new RowMapper<Blog>() {
        public Blog mapRow(ResultSet resultSet, int index) throws SQLException {
            return mapBlogHandler(resultSet);
        }
    });
}

11.6 getAll

public List<Blog> getAll() {
    String sql = "select * from blog ";
    return jt.query(sql, new RowMapper<Blog>() {
        public Blog mapRow(ResultSet resultSet, int index) throws SQLException {
            return mapBlogHandler(resultSet);
        }
    });
}

11.7 getTotalCount

public int getTotalCount() {
    String sql = "select count(1) from blog";
    return jt.queryForObject(sql, Integer.class);
}

12 jdbcTemplate 使用注解

  1. 启动注解扫描
<context:component-scan base-package="com.leiqingqi.pojo" />
  1. 不用配置xml 文件中的daoImpl bean
  2. 在 dao层配置注解
@Repository("blogDao")
public class BlogDaoImpl implements BlogDao {
    @Autowired
    private JdbcTemplate jt;
}

13 事务管理

导包 spring-tx

xml:

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

<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<property name="dataSource" ref="dataSource" ></property>
</bean>




    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="transfer" propagation="REQUIRED"/>
    </tx:attributes>

    </tx:advice>
    <aop:config>
        <aop:pointcut id="txPointcut" expression="execution(* com.leiqingqi.service..*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
    </aop:config>


14 事务管理注解

xml 开启注解

<tx:annotation-driven/>

service 层,事务管理管理的是service 层

只读事务只需要设置 read-only = "true" 就可以了

@Transactional(propagation = Propagation.REQUIRED,readOnly = false)
    public void transfer(Integer from, Integer to, Double money) throws PropertyVetoException {
        accountDao.subMoney(from, money);
        int t = 9 / 0;
        accountDao.addMoney(to, money);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值