Spring的IOC注解开发与AOP
本文内容纲要:
- 一 IOC实现的注解形式- 二 AOP的开发
一 IOC实现的注解形式
1SpringAOP的常用注解
官方建议使用这三个衍生注解,层次清晰,针对每一层
** @Controller web层**
** @Service service层**
** @Responsitory dao层**
@Autowired 注入对象,按类型注入。我们一般都是按照名称来注入,加一个Qualifier注解,必须让@Autowired和@Qualifier一起来使用,来完成按照名称的属性注入,
一般属性用value,对象属性用Resource
代码实现:
(1)编写UserDao的接口
package com.itheima.demo1;public interface UserDao {
public void save();
}
(2)ApplicationContext.xml配置
(3)编写UserDao的实现类
package com.itheima.demo1;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
//标记数据访问组件,即UserDao
@Repository("UserDao")
public class UserDaoImpl implements UserDao {
@Value("花花")
private String name;
@Override
public void save() {
System.out.println("UseDao的save方法执行了"+" 姓名是"+name);
}
}
(4)测试类
public class TestDemo1 { /**
* 使用注解的方式实现
* demo1使用的是UserDao
*/
@Test
public void demo1(){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao= (UserDao) applicationContext.getBean("UserDao");
userDao.save();
}
}
运行成功的结果图:
2 Bean作用的作用范围的注解(重点):
@scope
singleton:单例
prototype:多例
3 Bean的声明周期的注解
* 初始化的注解:PostCostrucct
销毁的注解:PerDestroy*
代码片段
4XML和注解的比较
XML:适合任何场景 特点:结构清晰,方便维护
注解:有些地方用不了(这个类不是自己提供的) 特点:开发方便
XML和注解整合开发(各取所长),XML管理Bean、注解属性注入
二 AOP的开发
1 什么是AOP?
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程。AOP是OOP的扩展、延申,解决oop开发遇到的问题。
利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
2 AOP采用的是横向抽取机制(代理机制)取代了传统的纵向继承.
Spring底层的AOP实现原理是动态代理
jdk的动态代理:只能对实现接口的类实现动态代理
Cglib动态代理(类似于Javassist第三方的动态代理)
3 jdk的动态代理部分代码实现
jdkProxy类
package com.baidu.demo;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkProxy implements InvocationHandler {
private UserService userService;
//把增强的对象传到proxy中
public JdkProxy(UserService userService) {
this.userService=userService;
}
public UserService createProxy(){
UserService Userproxy=(UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), this);//当时这里写错了
return Userproxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//如果是save方法,那么就加强
if("save".equals(method.getName())){
System.out.println("权限校验成功了.............");
return method.invoke(userService,args);
}
return method.invoke(userService,args);
}
}
4 Cglib动态代理的部分代码实现
package com.baidu.demo2;import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy implements MethodInterceptor {
//把要增强的类传进来
CustomerDao customerDao=new CustomerDao();
public CglibProxy(CustomerDao customerDao) {
this.customerDao = customerDao;
}
public CustomerDao createProxy(){
Enhancer enhancer=new Enhancer();
//设置父类
enhancer.setSuperclass(customerDao.getClass());
//设置回调
enhancer.setCallback(this);
CustomerDao customerDao = (CustomerDao) enhancer.create();
return customerDao;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//判断方法是否为空
if("save".equals(method.getName())){
//增强
System.out.println("权限校验成功啦.....");
return methodProxy.invokeSuper(proxy,args);
}
return methodProxy.invokeSuper(proxy,args);
}
}
5 Spring AOP的开发(基于Aspect J的XML方式)
你要想进行AOP的开发,就必须得了解一些相关的术语
Joinpoint:只要被拦截的点就成为连接点
Pointcut:切入点,真正被拦截到的点
Advice:通知、增强 增强的方法称为是通知,在方法执行之前,称为前置通知。日志记录、性能监控称为是后置通知
Introduction:引介。类层面的增强
Target:被增强的对象
Weaving:织入。通知应用(action)到目标Target的过程
Proxy:织入之后产生了一个代理对象
Aspect:切面多个通知和多个切入点的组合
6 Spring AOP的XML开发
通知类型(前三个是我们用的比较多的)
1前置通知 获得切入点的信息
2后置通知 获得返回值的类型,afterreturning
3环绕通知(功能最强的一个通知) proceed
4异常抛出通知 用于抛出异常的
5最终通知
无论有没有异常,最终通知总会执行的
(1)Aspect类
package com.baidu.demo3;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* 这是一个切面类
*/
public class aspetctJXMl {
/**
* 前置通知
* @param joinPoint
*/
//增强权限校验,提供增强的方法
public void checkPri(JoinPoint joinPoint) {
System.out.println("权限已经校验啦....." + joinPoint);
}
/**
* 后置通知
* @param result
* @return
*/
public String log(Object result){
System.out.println("日志已经记录下来了....."+result);
return "aa";
}
/**
* 环绕通知,功能最强的一个
* @param proceedingJoinPoint
* @return
*/
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕之前.......");
Object proceed = proceedingJoinPoint.proceed();
System.out.println("环绕之后.......");
return proceed;
}
/**
* 异常抛出通知
*/
public void afterThrowable(Throwable th){
System.out.println("异常抛出通知执行了....."+th);
}
/**
* 最终通知
*/
public void Final(){
System.out.println("最终通知执行了");
}
}
View Code
(2)在xml中的配置
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->
<bean id="productDao" class="com.baidu.demo3.ProductDaoImpl"/>
<!--将切面类交给spring管理-->
<bean id="aspect" class="com.baidu.demo3.aspetctJXMl"/>
<!--AOP的配置-->
<aop:config>
<aop:pointcut id="product1" expression="execution(* com.baidu.demo3.ProductDaoImpl.save(..))"/>
<aop:pointcut id="product2" expression="execution(* com.baidu.demo3.ProductDaoImpl.delete(..))"/>
<aop:pointcut id="product3" expression="execution(* com.baidu.demo3.ProductDaoImpl.update(..))"/>
<aop:pointcut id="product4" expression="execution(* com.baidu.demo3.ProductDaoImpl.find(..))"/>
<!--配置切面-->
<aop:aspect ref="aspect">
<!--前置通知-->
<aop:before method="checkPri" pointcut-ref="product1"/>
<!--后置通知-->
<aop:after-returning method="log" pointcut-ref="product2" returning="result"/>
<!--环绕通知-->
<aop:around method="around" pointcut-ref="product3" />
<!--异常抛出通知-->
<aop:after-throwing method="afterThrowable" pointcut-ref="product4" throwing="th"/>
<!--最终通知-->
<aop:after method="Final" pointcut-ref="product4"/>
</aop:aspect>
</aop:config>
</beans>
View Code
7 SPring AOP的注解开发
(1)Aspect类
package com.baidu.demo4;import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component //组件
@Aspect //切面多个通知和多个切入点的组合
public class aspect {
//声明一个公共的切入点
@Pointcut("execution(* com.baidu.demo4.UserService.*(..))") //任意返回值 任意方法 任意参数
public void myPointCut() {
}
//增强的方法
@Before("myPointCut()")
public void log() {
System.out.println("日志记录成功啦===============");
}
@After("myPointCut()")
public void save() {
System.out.println("性能检测成功啦=============");
}
@AfterThrowing("myPointCut()")
public void b() {
System.out.println("检测出来了异常===============");
}
}
(2)zhujie.xml
(3)测试类
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:zhujie.xml")
public class SpringTest2 {
@Resource
private UserService userService;
@Test
public void demo(){
userService.find();
userService.save();
userService.delete();
}
}
最后,附上一节的Spring框架的快速入门 https://www.cnblogs.com/bao6/p/10388760.html
英文单词:Component:组件
本文内容总结:一 IOC实现的注解形式,二 AOP的开发,
原文链接:https://www.cnblogs.com/bao6/p/10403049.html
以上是 Spring的IOC注解开发与AOP 的全部内容, 来源链接: utcz.com/z/296944.html