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

问题?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的形式有点儿是效率高,缺点是繁琐

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


你可能感兴趣的:(spring,bean,springAOP,SpringAOP注解解析)