Spring第二次练习——AOP

一、练习sop的编程,理解面向对象编程的含义

(一)了解AOP

AOP,面向切面编程。首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能。所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务;所谓的周边功能,比如性能统计,日志,事务管理等等,周边功能在Spring的面向切面编程AOP思想里,即被定义为切面;在面向切面编程AOP的思想里面,核心业务功能和切面功能分别独立进行开发,然后把切面功能和核心业务功能 "编织" 在一起,这就叫AOP。

(二)思路图

1. 功能分两大类,辅助功能和核心业务功能
2. 辅助功能和核心业务功能彼此独立进行开发
3. 比如登陆功能,即便是没有性能统计和日志输出,也可以正常运行
4. 如果有需要,就把"日志输出" 功能和 "登陆" 功能 编织在一起,这样登陆的时候,就可以看到日志输出了
5. 辅助功能,又叫做切面,这种能够选择性的,低耦合的把切面和核心业务功能结合在一起的编程思想,就叫做切面编程

 (三)练习

1、准备业务类 ProductService

 2、TestSpring:在引入切面之前,调用该业务类

 3、准备日志切面 LoggerAspect:该日志切面的功能是在调用核心功能之前和之后分别打印日志。

 4、applicationContext.xml

①声明业务对象

<bean name="s" class="com.how2java.service.ProductService">

</bean>

②声明日志切面

<bean id="loggerAspect" class="com.how2java.aspect.LoggerAspect"/>

 ③结合思路图指定右边的核心业务功能以及指定左边的辅助功能,然后通过aop:config把业务对象与辅助功能编织在一起。

<aop:pointcut id="loggerCutpoint"

expression=

"execution(* com.how2java.service.ProductService.*(..)) "/>

<aop:aspect id="logAspect" ref="loggerAspect">

<aop:around pointcut-ref="loggerCutpoint" method="log"/>

</aop:aspect>

5、TestSpring

注:TestSpring代码没有发生任何变化,只是通过配置的方式,把切面和核心业务类编制在了一起。运行结果如下,在编织之后,业务方法运行之前和之后分别会打印日志。

 

二、练习教材案例,体会编程式事务管理

此次练习的主要步骤:

1、编写Manager类用来装载配置文件,利用spring IOC创建TransactionExample对象并执行TransactionExample类的transactionOperation方法

package com.mr.main;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.mr.transaction.TransactionExample;
 
 
public class Manager {
 
    public static void main(String[] args) {
        ApplicationContext factory = new ClassPathXmlApplicationContext("applicationContext.xml"); 
        TransactionExample transactionExample = (TransactionExample) factory.getBean("transactionExample");
        transactionExample.transactionOperation();
    }
}

2、编写TransactionExample类:用setter,getter方法注入数据源,事务管理器与TransactionTemplate模板,并定义添加数据的方法,在方法中执行两次添加数据库操作操作并用事务保护操作

package com.mr.transaction;
 
import java.sql.Connection;
import java.sql.Statement;
 
import javax.sql.DataSource;
 
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
 
public class TransactionExample {
    DataSource dataSource;
    PlatformTransactionManager transactionManager;
    TransactionTemplate transactionTemplate;
    public DataSource getDataSource() {
        return dataSource;
    }
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }
    public PlatformTransactionManager getTransactionManager() {
        return transactionManager;
    }
    public void setTransactionManager(PlatformTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }
    public TransactionTemplate getTransactionTemplate() {
        return transactionTemplate;
    }
    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }
    public void transactionOperation() {
        transactionTemplate.execute(new TransactionCallback() {
            public Object doInTransaction(TransactionStatus status) {
                Connection conn = DataSourceUtils.getConnection(dataSource);
                try {
                    Statement stmt = conn.createStatement();
                    
                    stmt.execute("insert into tb_user(name,age,xingbie) values('jinghua','23','男')");
                    int a=0;
                    a=9/a;
                    stmt.execute("insert into tb_user(name,age,xingbie) values('xi','18','男')");
                    System.out.println("操作执行成功!");
                } catch (Exception e) {
                    transactionManager.rollback(status);//事务回滚
                    System.out.println("操作执行失败,事务回滚!");
                    System.out.println("原因:"+e.getMessage());
                }
                return null;
            }
        });
    }
}

3、编写配置文件:定义数据源,连接数据库的配置;定义事务管理器;定义TransactionExample模板;并为TransactionExample注入数据源 、事务管理器、TransactionTemplate模板

<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
	<!-- 配置数据源 -->
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName">
			<value>com.mysql.jdbc.Driver</value>
		</property>
		<property name="url">
			<value>jdbc:mysql://localhost:3306/test
			</value>
		</property>
		<property name="username">
			<value>root</value>
		</property>
		<property name="password">
			<value>wal6775374wal</value>
		</property>
	</bean>
	<!-- 定义TransactionTemplate模板 -->
	<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
		<property name="transactionManager">
			<ref bean="transactionManager"/>
		</property>
		<property name="propagationBehaviorName">
			<value>PROPAGATION_REQUIRED</value>
		</property>
	</bean>
	<!-- 定义事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
	</bean>
	<!-- 为TransactionExample注入数据源 、事务管理器、TransactionTemplate模板-->
	<bean id="transactionExample"
		class="com.mr.transaction.TransactionExample">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<property name="transactionManager">
			<ref bean="transactionManager" />
		</property>
		<property name="transactionTemplate">
			<ref bean="transactionTemplate"/>
		</property>
	</bean>
</beans>

为了测试事务是否配置成功,在transactionOperation方法中执行两次添加操作之间添加制造人为的异常(int a=0;a=9/a;),即当第一条操作语句执行成功后,第二条操作语句因为程序的异常无法执行成功。如果此时事务回滚成功,说明事务配置成功。


 

  输出事务回滚,说明事务配置成功,且表中并未插入数据。

三、练习教材案例,体会声明式事务管理

练习中的主要步骤:

1、编写配置文件:定义数据源、连接数据库的配置;定义事务管理器;定义TransactionProxy,并将事务管理器注入其中,设置代理对象和事务属性,且这里以内部类的形式指定代理的目标对象。

<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
	<!-- 配置数据源 -->
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName">
			<value>com.mysql.jdbc.Driver</value>
		</property>
		<property name="url">
			<value>jdbc:mysql://localhost:3306/test</value>
		</property>
		<property name="username">
			<value>root</value>
		</property>
		<property name="password">
			<value>wal6775374wal</value>
		</property>
	</bean>
	<!-- 定义事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
	</bean>
	<!-- 定义TransactionProxy -->
	<bean id="transactionProxy"
		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
		<property name="transactionManager">
			<ref local="transactionManager" />
		</property>
		<property name="target">
		<!-- 以内部类的形式指定代理的目标对象 -->
			<bean id="addDAO" class="com.mr.dao.AddDAO">
				<property name="dataSource">
					<ref local="dataSource" />
				</property>
			</bean>
		</property>
		<property name="proxyTargetClass" value="true" />
		<property name="transactionAttributes">
			<props>
			<!-- 通过正则表达式匹配事务性方法,并指定方法的事务属性,即代理对象中只要是以add开头的方法名必须运行在事务中 -->
				<prop key="add*">PROPAGATION_REQUIRED</prop>
			</props>
		</property>
	</bean>
</beans>

2、编写AddDAO类:编写两次数据插入操作的方法,并在配置TransactionProxyFactoryBean时被定义为事务性方法,所以该方法中所有数据库操作都被当作一个事务处理。并在其中制造异常测试事务是否配置成功,与上个练习类似。

package com.mr.dao;
 
 
import org.springframework.jdbc.core.support.JdbcDaoSupport;
 
import com.mr.user.User;
 
public class AddDAO extends JdbcDaoSupport {
    //添加用户的方法
    public void addUser(User user){
        //执行添加方法的sql语句
        String sql="insert into tb_user (name,age,xingbie) values('" + 
                    user.getName() + "','" + user.getAge()+ "','" + user.getSex()+ "')";
        //执行两次添加方法
        getJdbcTemplate().execute(sql);
        int a=0;//制造异常测试事务是否配置成功
        a=9/a;
        getJdbcTemplate().execute(sql);
    }
}

3、编写Manager类:装载配置文件,获取AddDAO,实例化User实体对象并设置姓名、年龄、性别,调用addUser方法执行数据库添加方法。

package com.mr.main;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.mr.dao.AddDAO;
import com.mr.user.User;
 
public class Manager {
    public static void main(String[] args) {
    	ApplicationContext factory = new ClassPathXmlApplicationContext("applicationContext.xml");  //装载配置文件
        AddDAO addDAO = (AddDAO)factory.getBean("transactionProxy");//获取AddDAO
        User user = new User();//实例化User实体对象
        user.setName("huaxi");//设置姓名
        user.setAge(18);//设置年龄
        user.setXingbie("男");//设置性别
        addDAO.addUser(user);//执行数据库添加方法
    }
}

4、User.java

package com.mr.user;
 
public class User {
    
    private String name;//姓名
    
    private Integer age;//年龄
    
    private String xingbie;//性别
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Integer getAge() {
        return age;
    }
 
    public void setAge(Integer age) {
        this.age = age;
    }
 
    public String getXingbie() {
        return xingbie;
    }
 
    public void setXingbie(String xingbie) {
        this.Xingbie = xingbie;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOPSpring框架中的一个重要模块,它提供了面向切面编程(AOP)的支持。AOP是一种编程思想,它可以在不改变原有代码的情况下,通过在程序运行时动态地将代码“织入”到现有代码中,从而实现对原有代码的增强。 Spring AOP提供了基于注解的AOP实现,使得开发者可以通过注解的方式来定义切面、切点和通知等相关内容,从而简化了AOP的使用。 下面是一个基于注解的AOP实现的例子: 1. 定义切面类 ```java @Aspect @Component public class LogAspect { @Pointcut("@annotation(Log)") public void logPointcut() {} @Before("logPointcut()") public void beforeLog(JoinPoint joinPoint) { // 前置通知 System.out.println("执行方法:" + joinPoint.getSignature().getName()); } @AfterReturning("logPointcut()") public void afterLog(JoinPoint joinPoint) { // 后置通知 System.out.println("方法执行完成:" + joinPoint.getSignature().getName()); } @AfterThrowing(pointcut = "logPointcut()", throwing = "ex") public void afterThrowingLog(JoinPoint joinPoint, Exception ex) { // 异常通知 System.out.println("方法执行异常:" + joinPoint.getSignature().getName() + ",异常信息:" + ex.getMessage()); } } ``` 2. 定义业务逻辑类 ```java @Service public class UserService { @Log public void addUser(User user) { // 添加用户 System.out.println("添加用户:" + user.getName()); } @Log public void deleteUser(String userId) { // 删除用户 System.out.println("删除用户:" + userId); throw new RuntimeException("删除用户异常"); } } ``` 3. 在配置文件中开启AOP ```xml <aop:aspectj-autoproxy/> <context:component-scan base-package="com.example"/> ``` 在这个例子中,我们定义了一个切面类LogAspect,其中通过@Aspect注解定义了一个切面,通过@Pointcut注解定义了一个切点,通过@Before、@AfterReturning和@AfterThrowing注解分别定义了前置通知、后置通知和异常通知。 在业务逻辑类中,我们通过@Log注解标注了需要增强的方法。 最后,在配置文件中,我们通过<aop:aspectj-autoproxy/>开启了AOP功能,并通过<context:component-scan>扫描了指定包下的所有组件。 这样,当我们调用UserService中的方法时,就会触发LogAspect中定义的通知,从而实现对原有代码的增强。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值