* AOP (Aspect Oriented Programing)--面向切面编程
* AOP相关术语
Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点
Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义
Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)
Target(目标对象):代理的目标对象
Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程
spring采用动态代理织入,而AspectJ采用编译期织入和类装在期织入
Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类
Aspect(切面): 是切入点和通知的结合
* jdk动态代理
IUserDao proxy = (IUserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao
.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object o = method.invoke(userDao, args);//在代理对象中调用目标对象的方法
if(method.getName().equals("save")){
System.out.println("在代理对象中拦截到的目标对象的方法为:" + method.getName());
System.out.println("在代理对象中记录日志。。。");
}
return o;
}
});
* cglib动态代理
Enhancer eh = new Enhancer();
eh.setSuperclass(UserService.class);//指定父类,为谁产生代理
eh.setCallback(new MethodInterceptor() {
public Object intercept(Object arg0, Method method, Object[] arg,
MethodProxy arg3) throws Throwable {
Object o = null;
if(method.getName().equals("save")){
System.out.println("在代理对象中开启事务。。。 ");
//在代理对象中调用目标对象的方法
o = method.invoke(userService, arg);
System.out.println("在代理对象中提交事务。。。 ");
}else{
o = method.invoke(userService, arg);
}
return o;
}
});//指定回调
* AOP联盟为通知Advice定义了org.aopalliance.aop.Interface.Advice
* spring AOP 中对通知做扩展
前置通知 org.springframework.aop.MethodBeforeAdvice
在目标方法执行前实施增强
后置通知 org.springframework.aop.AfterReturningAdvice
在目标方法执行后实施增强
环绕通知 org.aopalliance.intercept.MethodInterceptor
在目标方法执行前后实施增强
异常抛出通知 org.springframework.aop.ThrowsAdvice
在方法抛出异常后实施增强
引介通知 org.springframework.aop.IntroductionInterceptor
在目标类中添加一些新的方法和属性
* Spring AOP切面类型
1)Advisor : 代表一般切面,Advice本身就是一个切面,对目标类所有方法进行拦截
2)PointcutAdvisor : 代表具有切点的切面,可以指定拦截目标类哪些方法
* spring中自动创建代理
1)BeanNameAutoProxyCreator 根据Bean名称创建代理 (针对Bean所有方法)
2)DefaultAdvisorAutoProxyCreator 根据Advisor本身包含信息创建代理 (针对特定的方法)
*使用AOP框架AspectJ(注解方式)
1)导入jar包
spring-aop-3.2.0.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
spring-aspects-3.2.0.RELEASE.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
2)导入约束
<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">
3)开启AspectJ的自动代理功能
<aop:aspectj-autoproxy />
4)定义目标类UserDao
5)定义一个切面类
@Aspect
public class MyAdvisor {
//提供一个方法,作为前置通知
@Before(value = "execution(* cn.itcast.aspectJ.UserDao.*(..))")
public void before1(){
System.out.println("前置通知执行了。。。");
}
@Before(value = "execution(* cn.itcast.aspectJ.UserDao.*(..))")
public void before2(JoinPoint jp) {
System.out.println("在前置通知中拦截到了一个方法:" + jp.getSignature().getName());
}
@AfterReturning(value = "execution(* cn.itcast.aspectJ.UserDao.*(..))",returning = "retVal")
public void afterReturning1(JoinPoint jp,Object retVal){
System.out.println("后置通知执行了。。。,拦截到的方法返回值为:" + retVal);
}
}
6)将目标类和切面类注册到beans.xml中
<bean id="userDao" class="cn.itcast.aspectJ.UserDao"></bean>
<bean id="myAdvisor" class="cn.itcast.aspectJ.MyAdvisor"></bean>
7)初始化spring工厂,获取代理对象
ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/itcast/aspectJ/beans.xml");
UserDao userDao = (UserDao) ctx.getBean("userDao");
userDao.delete();
* 使用AOP框架AspectJ(XML方式)
1)导入jar包
spring-aop-3.2.0.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
spring-aspects-3.2.0.RELEASE.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
2)导入约束
<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">
3)开启AspectJ的自动代理功能
<aop:aspectj-autoproxy />
4)定义目标类UserDao
5)定义一个切面类
public class MyAdvisor{
public void before1(){
System.out.println("前置通知执行了。。");
}
}
6)将目标类和切面类注册到beans.xml中
<bean id="userDao" class="cn.itcast.aspectJ.UserDao"></bean>
<bean id="myAdvisor" class="cn.itcast.aspectJ.MyAdvisor"></bean>
7)在beans.xml中配置
<aop:config>
<aop:aspect ref="myAdvisor">
<!-- 定义切入点 -->
<aop:pointcut expression="execution(* cn.itcast.aspectJ.xml.*Dao.*(..))" id="myPC"/>
<aop:before method="before1" pointcut-ref="myPC"/>
<aop:after-returning method="afterReturning1" pointcut-ref="myPC" returning="retVal"/>
<aop:around method="around1" pointcut-ref="myPC"/>
<aop:after-throwing method="throwing1" pointcut-ref="myPC"/>
<aop:after method="after1" pointcut-ref="myPC"/>
</aop:aspect>
</aop:config>
* JDBCTemplate
* Spring对不同持久化技术的支持
JDBC org.springframework.jdbc.core.JdbcTemplate
Hibernate3.0 org.springframework.orm.hibernate3.HibernateTemplate
IBatis(MyBatis) org.springframework.orm.ibatis.SqlMapClientTemplate
JPA org.springframework.orm.jpa.JpaTemplate
* 使用jdbc模板
1)导入jar(beans,core ,context,expression,jdbc,tx ,database driver)
2)创建数据库和表
create database jdbcTemplate default character set utf8;
use jdbcTemplate;
create table itcast_user(id int primary key auto_increment,name varchar(32),age int,address varchar(128));
3)创建一个实体类User
4)提供一个spring的配置文件beans.xml(数据源,dao,service,jdbcTemplate)
5) 从spring工厂中获取service操作
* AOP相关术语
Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点
Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义
Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)
Target(目标对象):代理的目标对象
Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程
spring采用动态代理织入,而AspectJ采用编译期织入和类装在期织入
Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类
Aspect(切面): 是切入点和通知的结合
* jdk动态代理
IUserDao proxy = (IUserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao
.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object o = method.invoke(userDao, args);//在代理对象中调用目标对象的方法
if(method.getName().equals("save")){
System.out.println("在代理对象中拦截到的目标对象的方法为:" + method.getName());
System.out.println("在代理对象中记录日志。。。");
}
return o;
}
});
* cglib动态代理
Enhancer eh = new Enhancer();
eh.setSuperclass(UserService.class);//指定父类,为谁产生代理
eh.setCallback(new MethodInterceptor() {
public Object intercept(Object arg0, Method method, Object[] arg,
MethodProxy arg3) throws Throwable {
Object o = null;
if(method.getName().equals("save")){
System.out.println("在代理对象中开启事务。。。 ");
//在代理对象中调用目标对象的方法
o = method.invoke(userService, arg);
System.out.println("在代理对象中提交事务。。。 ");
}else{
o = method.invoke(userService, arg);
}
return o;
}
});//指定回调
* AOP联盟为通知Advice定义了org.aopalliance.aop.Interface.Advice
* spring AOP 中对通知做扩展
前置通知 org.springframework.aop.MethodBeforeAdvice
在目标方法执行前实施增强
后置通知 org.springframework.aop.AfterReturningAdvice
在目标方法执行后实施增强
环绕通知 org.aopalliance.intercept.MethodInterceptor
在目标方法执行前后实施增强
异常抛出通知 org.springframework.aop.ThrowsAdvice
在方法抛出异常后实施增强
引介通知 org.springframework.aop.IntroductionInterceptor
在目标类中添加一些新的方法和属性
* Spring AOP切面类型
1)Advisor : 代表一般切面,Advice本身就是一个切面,对目标类所有方法进行拦截
2)PointcutAdvisor : 代表具有切点的切面,可以指定拦截目标类哪些方法
* spring中自动创建代理
1)BeanNameAutoProxyCreator 根据Bean名称创建代理 (针对Bean所有方法)
2)DefaultAdvisorAutoProxyCreator 根据Advisor本身包含信息创建代理 (针对特定的方法)
*使用AOP框架AspectJ(注解方式)
1)导入jar包
spring-aop-3.2.0.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
spring-aspects-3.2.0.RELEASE.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
2)导入约束
<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">
3)开启AspectJ的自动代理功能
<aop:aspectj-autoproxy />
4)定义目标类UserDao
5)定义一个切面类
@Aspect
public class MyAdvisor {
//提供一个方法,作为前置通知
@Before(value = "execution(* cn.itcast.aspectJ.UserDao.*(..))")
public void before1(){
System.out.println("前置通知执行了。。。");
}
@Before(value = "execution(* cn.itcast.aspectJ.UserDao.*(..))")
public void before2(JoinPoint jp) {
System.out.println("在前置通知中拦截到了一个方法:" + jp.getSignature().getName());
}
@AfterReturning(value = "execution(* cn.itcast.aspectJ.UserDao.*(..))",returning = "retVal")
public void afterReturning1(JoinPoint jp,Object retVal){
System.out.println("后置通知执行了。。。,拦截到的方法返回值为:" + retVal);
}
}
6)将目标类和切面类注册到beans.xml中
<bean id="userDao" class="cn.itcast.aspectJ.UserDao"></bean>
<bean id="myAdvisor" class="cn.itcast.aspectJ.MyAdvisor"></bean>
7)初始化spring工厂,获取代理对象
ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/itcast/aspectJ/beans.xml");
UserDao userDao = (UserDao) ctx.getBean("userDao");
userDao.delete();
* 使用AOP框架AspectJ(XML方式)
1)导入jar包
spring-aop-3.2.0.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
spring-aspects-3.2.0.RELEASE.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
2)导入约束
<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">
3)开启AspectJ的自动代理功能
<aop:aspectj-autoproxy />
4)定义目标类UserDao
5)定义一个切面类
public class MyAdvisor{
public void before1(){
System.out.println("前置通知执行了。。");
}
}
6)将目标类和切面类注册到beans.xml中
<bean id="userDao" class="cn.itcast.aspectJ.UserDao"></bean>
<bean id="myAdvisor" class="cn.itcast.aspectJ.MyAdvisor"></bean>
7)在beans.xml中配置
<aop:config>
<aop:aspect ref="myAdvisor">
<!-- 定义切入点 -->
<aop:pointcut expression="execution(* cn.itcast.aspectJ.xml.*Dao.*(..))" id="myPC"/>
<aop:before method="before1" pointcut-ref="myPC"/>
<aop:after-returning method="afterReturning1" pointcut-ref="myPC" returning="retVal"/>
<aop:around method="around1" pointcut-ref="myPC"/>
<aop:after-throwing method="throwing1" pointcut-ref="myPC"/>
<aop:after method="after1" pointcut-ref="myPC"/>
</aop:aspect>
</aop:config>
* JDBCTemplate
* Spring对不同持久化技术的支持
JDBC org.springframework.jdbc.core.JdbcTemplate
Hibernate3.0 org.springframework.orm.hibernate3.HibernateTemplate
IBatis(MyBatis) org.springframework.orm.ibatis.SqlMapClientTemplate
JPA org.springframework.orm.jpa.JpaTemplate
* 使用jdbc模板
1)导入jar(beans,core ,context,expression,jdbc,tx ,database driver)
2)创建数据库和表
create database jdbcTemplate default character set utf8;
use jdbcTemplate;
create table itcast_user(id int primary key auto_increment,name varchar(32),age int,address varchar(128));
3)创建一个实体类User
4)提供一个spring的配置文件beans.xml(数据源,dao,service,jdbcTemplate)
5) 从spring工厂中获取service操作