Spring-Aop注解形式案例<三>

本文详细介绍了Spring框架中使用注解形式实现AOP(面向切面编程)的案例,包括工具类、持久化类、映射文件、目标接口、目标类以及切面类的实现,并通过应用上下文配置文件进行整合。通过实际代码示例,展示了如何在Spring环境中运用AOP注解来管理业务逻辑,实现代码的解耦与复用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题?Spring-Aop注解形式案例

我们知道,在spring中,spring提供了注解的形式,来达到对象的依赖注入。当然我们也可以直接用依赖注入将bean


这里写的是Spring-Aop注解形式案例

工具类:

package cn.itcast.spring.sh.aop;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class HibernateUtils {
	public static SessionFactory sessionFactory;
	static{
		Configuration configuration = new Configuration();
		configuration.configure("cn/itcast/spring/sh/aop/hibernate.cfg.xml");
		sessionFactory = configuration.buildSessionFactory();
//		Session session = sessionFactory.openSession();
//		Transaction transaction = session.beginTransaction();
//		transaction.commit();
	}
}

持久化类:Person

package cn.itcast.spring.sh.aop;

import java.io.Serializable;

public class Person implements Serializable{
	private Long pid;
	private String pname;
	private String psex;
	
	public Person(){}
	
	public Person(String pname){
		this.pname = pname;
	}
	
	public Long getPid() {
		return pid;
	}
	public void setPid(Long pid) {
		this.pid = pid;
	}
	public String getPname() {
		return pname;
	}
	public void setPname(String pname) {
		this.pname = pname;
	}
	public String getPsex() {
		return psex;
	}
	public void setPsex(String psex) {
		this.psex = psex;
	}
	
}

映射文件:Person.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
	<!-- 
		用来描述一个持久化类
		name  类的全名
	 	table 可以不写  默认值和类名一样 
	 	catalog  数据库的名称  一般不写
	 -->
	<class name="cn.itcast.spring.sh.aop.Person">
		<!-- 
			标示属性  和数据库中的主键对应
			name  属性的名称
			column 列的名称
		 -->
		<id name="pid" column="pid" length="200" type="java.lang.Long">
			<!-- 
				主键的产生器
				  就该告诉hibernate容器用什么样的方式产生主键
			 -->
			<generator class="increment"></generator>
		</id>
		<!-- 
			描述一般属性
		 -->
		<property name="pname" column="pname" length="20" type="string"></property>
		
		<property name="psex" column="psex" length="10" type="java.lang.String"></property>
	</class>
</hibernate-mapping>

hibernate配置文件:hibernate.cfg.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
	<!-- 
		用来描述一个持久化类
		name  类的全名
	 	table 可以不写  默认值和类名一样 
	 	catalog  数据库的名称  一般不写
	 -->
	<class name="cn.itcast.spring.sh.aop.Person">
		<!-- 
			标示属性  和数据库中的主键对应
			name  属性的名称
			column 列的名称
		 -->
		<id name="pid" column="pid" length="200" type="java.lang.Long">
			<!-- 
				主键的产生器
				  就该告诉hibernate容器用什么样的方式产生主键
			 -->
			<generator class="increment"></generator>
		</id>
		<!-- 
			描述一般属性
		 -->
		<property name="pname" column="pname" length="20" type="string"></property>
		
		<property name="psex" column="psex" length="10" type="java.lang.String"></property>
	</class>
</hibernate-mapping>

目标接口:(这里我们采用jdk的形式(实现接口))

package cn.itcast.spring.sh.aop;

public interface PersonDao {
	public String savePerson(Person person);
}

目标类:

package cn.itcast.spring.sh.aop;


import org.springframework.stereotype.Repository;

@Repository("personDao1")
public class PersonDaoImpl extends HibernateUtils implements PersonDao  {

	public String savePerson(Person person) {
		sessionFactory.getCurrentSession().save(person);
		System.out.println("执行保存操作了。");
		return "返回值";
	}
	


}

切面类:

package cn.itcast.spring.sh.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.hibernate.Transaction;
import org.springframework.stereotype.Component;

/**
 * @Aspect
 * @author Administrator
 *	Aspect相当于<aop:config></aop:config>
 */
@Component("myTransaction")
@Aspect
public class MyTransaction extends HibernateUtils {
	private Transaction transaction;
	
	/**
	 * 通过一些参数可以获取目标方法的相关信息,报告目标方法名称、返回值参数、异常信息等
	 * 不过相应的也要在配置文件中进行设置(通过实验,好像只配置后置及异常就可以只用了),不然就获取不了。
	 * 注:环绕通知不可以跟前置通知和后置通知一起用,因为环绕通知已经把两个通知的东西做了,它可以调用目标方法
	 * 
	 * */
	
	//写这个的目的就相当于早aop配置中写了:
		//<aop:pointcut expression="execution(* cn.itcast.spring.sh.aop.PersonDaoImpl.*(..))" id="aa()"/>
	@Pointcut("execution(* cn.itcast.spring.sh.aop.PersonDaoImpl.*(..))")
	private void aa(){}//叫方法签名:方法类型必须是void,修饰符最好是pivate
	
	
	//注解形式:前置通知
	@Before("aa()")
	public void beginTransaction(JoinPoint joinPoint){
		System.out.println("开启事务");
		this.transaction = sessionFactory.getCurrentSession().beginTransaction();
		
	}
	
	//注解形式:后置通知
	@AfterReturning(value="aa()",returning="val")
	public void commit(Object val){
		//提交事务
		this.transaction.commit();
		System.out.println("关闭事务");
	}
	
}

applicationContext.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:context="http://www.springframework.org/schema/context"
	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
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">


<!-- AOP注解讲解 :将目标类和切面放入到spring容器管理,启动扫描注解解析器  注:一般不用这个,因为有弊端-->
	<!-- 
		使用条件:
		AOP的条件如下
		xmlns:aop="http://www.springframework.org/schema/aop" 
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
		
		扫描注解解析器的条件如下
		xmlns:context="http://www.springframework.org/schema/context"
		http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-2.5.xsd" 
	-->
	 <context:component-scan base-package="cn.itcast.spring.sh.aop"></context:component-scan>
	 <!-- 启动aop的注解解析器 -->
	 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

测试类:

package cn.itcast.spring.sh.aop;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class PersonTest {
	@Test
	public void test(){
		ApplicationContext applicationContext = new  ClassPathXmlApplicationContext("cn/itcast/spring/sh/aop/applicationContext.xml");
		PersonDao personDao = (PersonDao)applicationContext.getBean("personDao1");
		Person person1 = new Person();
		person1.setPname("李大鹏11");
		person1.setPsex("男");
		personDao.savePerson(person1);
	} 
}

结果:



总结:想对来说,不管是用xml的形式来实现,还是用注解的方式来实现,都可以。xml的形式有点儿是效率高,缺点是繁琐

注解的缺点是效率低,优点是简单。


<think>嗯,用户导入了Spring Context和AspectJ Weaver的依赖,但没出现Spring Config的问题。首先,我需要理清楚这两个依赖的作用。Spring Context是Spring框架的核心,提供IoC和依赖注入功能,而AspectJ Weaver用于支持AOP,比如切面编程。 用户提到“没有出现Spring Config”,可能是指在IDE里没有自动生成配置,或者在项目结构中找不到相关配置。常见的情况是,用户可能期望Spring自动生成配置文件,但实际上需要手动创建。比如,Spring的XML配置文件(如applicationContext.xml)或Java配置类(带@Configuration的类)需要用户自己创建,Spring不会自动生成。 另外,检查依赖是否正确引入。用户提供的Maven依赖版本是5.1.11.RELEASE和AspectJ 1.9.6,可能存在版本兼容性问题吗?不过这两个版本通常是兼容的,但需要确认是否有冲突。用户是否执行了Maven的重新导入?有时候依赖没下载完全会导致问题。 还有,是否缺少必要的配置?比如,如果使用注解驱动,需要在配置类上添加@EnableAspectJAutoProxy,或者在XML中配置<aop:aspectj-autoproxy/>。如果用户没有正确配置这些,即使有AspectJ Weaver的依赖,AOP也不会生效,导致Spring Config不出现。 另外,项目结构是否正确?比如,配置文件是否放在src/main/resources目录下,或者配置类是否在组件扫描的包路径下。如果配置类不在扫描范围内,Spring不会加载它,导致配置无效。 用户可能混淆了依赖引入和配置创建。添加依赖只是提供了库的支持,但具体的配置需要用户自行设置。比如,使用Java配置或XML配置来定义Bean和切面。如果用户没有创建这些配置,Spring自然不会自动生成。 还有可能用户期望IDE的某些功能,比如Spring Tools Suite的仪表盘或配置支持,但普通项目可能需要手动启用Spring插件或配置。或者,用户可能没有正确设置Spring Facet,导致IDE没有识别到Spring项目结构。 最后,是否需要检查构建工具的输出,确认依赖是否被正确下载,没有出现错误或冲突。比如,Maven的pom.xml是否正确,依赖是否下载到本地仓库,是否存在网络问题导致依赖下载失败。</think>你遇到的问题可能有以下几个原因,以下从依赖作用和配置方式逐步分析: 1. **依赖作用分析** - `spring-context`: 提供Spring核心容器功能(IoC/DI)和基础注解支持 $$ \text{Spring Context} \supset \{ \text{@Component, @Autowired, @Configuration} \} $$ - `aspectjweaver`: 提供AspectJ切面织入能力(配合`@Aspect`使用) 2. **未出现Spring Config的可能原因** **情况一:未主动创建配置文件** - 需要手动创建以下两种配置之一: - **XML配置**:`src/main/resources/applicationContext.xml` ```xml <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="..."> <context:component-scan base-package="com.example"/> <aop:aspectj-autoproxy/> </beans> ``` - **Java配置类**:`@Configuration`标注的类 ```java @Configuration @ComponentScan("com.example") @EnableAspectJAutoProxy public class AppConfig {} ``` **情况二:配置未被正确加载** - **XML配置需要初始化容器**: ```java ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); ``` - **Java配置需要初始化容器**: ```java AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); ``` 3. **验证步骤** ```mermaid graph TD A[检查依赖] -->|mvn dependency:tree| B[确认spring-conject存在] B --> C[检查配置文件位置] C --> D[确认是否启用组件扫描] D --> E[验证AOP代理是否启用] ``` 4. **典型成功案例** ```java // 定义切面 @Aspect @Component public class LoggingAspect { @Before("execution(* com.example.service.*.*(..))") public void logBefore(JoinPoint joinPoint) { System.out.println("方法执行: " + joinPoint.getSignature()); } } // 主程序 public class MainApp { public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); MyService service = ctx.getBean(MyService.class); service.execute(); } } ``` 5. **版本兼容性建议** - Spring 5.1.x 推荐配合 AspectJ 1.9.x 使用 - 若需使用最新特性,可升级至: ```xml <version>5.3.27</version> <!-- spring-context --> <version>1.9.19</version> <!-- aspectjweaver --> ``` 请根据实际项目结构检查配置文件位置和加载方式,若仍无法解决建议提供具体错误日志。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值