问题?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的形式有点儿是效率高,缺点是繁琐
注解的缺点是效率低,优点是简单。