使用注解方式实现 AOP和IoC

Posted 1314justin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用注解方式实现 AOP和IoC相关的知识,希望对你有一定的参考价值。

使用注解方式实现AOPIoC

 

IOCDI的注解

                          IOC:

                          @Component:实现Bean组件的定义

                          @Repository:用于标注DAO类,功能与@Component作用相当

                          @Service:用于标注业务类

                          @Controller:用于标注控制器

              DI:

                          @Resource(name="userService")

                               默认ByName方式,如果name确实默认按照ByType方式注入

                          @Autowired

                              默认ByType方式,如果出现同名类,则不能按照Type进行注入

                            需要使用@Qualifier 指明ID

 

 

1.  使用注解实现IoC案例

 

1.1 编写applicationContext.xm文件
<!--扫描注解:包扫描器-->
<context:component-scan base-package="cn.spring"/>

 

 

1.2创建mapper接口
public interface UserMapper {
    public int addUser(User user);
}

 

 

 

1.3 创建mapper接口实现类
@Repository
public class UserMapperImpl implements UserMapper {

    @Override
    public int addUser(User user) {
        System.out.println("添加成功");
        return 1;
    }
}

 

 

 

1.4创建Service接口
public interface UserService {
    public int addUser(User user);
}

 

 

 

 

1.5创建Service接口实现类
@Service("userServiceImpl")
public class UserServiceImpl implements UserService {
    //植入Dao层对象
    //@Resource默认是根据byName的方式,但是一旦名字为空 ,就根据byType
    @Autowired
    private UserMapper userMapper;
    @Override
    public int addUser(User user) {

        return userMapper.addUser(user);
    }

}

 

 

 

1.6 编写测试类
@org.junit.Test
public void test2() {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    //通过类型调度
    //UserInfoService userService=context.getBean(UserService.class);
    //指定@Service的value值后使用bean的id名称调度
    UserService userServiceImpl = (UserService) context.getBean("userServiceImpl");
    userServiceImpl.addUser(new User());
}

 

 

1.7 控制台

 技术图片

 

 

 

 

使用注解方式实现AOP

  • 实现AOP的注解有
  • @Aspect 声明切面
  • @Ponitcut 声明公共的切点表达式
  • @Before 前置增强
  • @AfterReturning 后置增强
  • @Around 环绕增强
  • @AfterThrowing 异常抛出增强
  • @After 最终增强

  1.使用注解方式实现前置增强和后置增强

    1.1  编写applicationContext.xml文件

<!--开启AOP注解支持-->
<aop:aspectj-autoproxy/>

 

 

    1.2 创建Service类

@Service("IDoSomeService")
public class IDoSomeService {

    public void doSome(){
        System.out.println("业务类中dosome方法");
    }


    public void say(){
        System.out.println("业务类中say方法");
    }
}

 

 

    1.3 编写切面类实现增强

@Aspect
@Component
public class MyAdvice {
    
@Pointcut("execution(* *..service.*.*(..))")
public void point(){

}

    @Before("point()")
    public void before(){
        System.out.println("前置增强");
    }


    @AfterReturning("execution(* *..service.*.*(..))")
    public void afterReturning(){
        System.out.println("后置增强");
    }

}

 

 

    1.4 编写测试类

@org.junit.Test
public void test3(){
    ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    IDoSomeService iDoSomeService = (IDoSomeService)context.getBean("IDoSomeService");
    iDoSomeService.doSome();
    iDoSomeService.say();
}

 

 

    1.5 控制台

 技术图片

 

 

 

 

 

  2. 使用注解方式实现环绕增强

    2.1  编写applicationContext.xml文件

<!--扫描注解:包扫描器-->
<context:component-scan base-package="cn.spring"/>

<!--开启AOP注解支持-->
<aop:aspectj-autoproxy/>

 

 

    2.2 创建Service类

@Service("IDoSomeService")
public class IDoSomeService {

    public void doSome(){
        System.out.println("业务类中dosome方法");
    }


    public void say(){
        System.out.println("业务类中say方法");
    }
}

 

 

    2.3编写切面类实现增强

@Aspect
@Component
public class AroundAdvisor {

    @Around("execution(* *..service.*.*(..))")
    public void around(ProceedingJoinPoint PJ) throws Throwable {
        System.out.println("环绕增强");
        PJ.proceed();
        System.out.println("环绕增强");
    }
}

 

 

    2.4编写测试类

@org.junit.Test
public void test3(){
    ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    IDoSomeService iDoSomeService = (IDoSomeService)context.getBean("IDoSomeService");
    iDoSomeService.doSome();
    iDoSomeService.say();
}

 

 

    2.5控制台

 技术图片

 

 

 

 

3. 使用注解实现异常抛出增强

           exception包下完成对应的用例。

           声明切面类

 

@Aspect
public class AroundLoggerAnno {
   @Around("execution(* com.cmy.service.*.*(..))")
   public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable {
      System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
            + " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
      try {
         Object result = jp.proceed();
         System.out.println("调用 " + jp.getTarget() + " 的 "
               + jp.getSignature().getName() + " 方法。方法返回值:" + result);
         return result;
      } catch (Throwable e) {
         System.out.println(jp.getSignature().getName() + " 方法发生异常:" + e);
         throw e;
      } finally {
         System.out.println(jp.getSignature().getName() + " 方法结束执行。");
      }
   }

 

 

 

   创建Spring的核心配置文件,开启Spring对IOC和AOP注解的支持

新增app-08.xml文件

 

<!--开启Spring IOC的注解支持 base-package 包扫描语句 com.cmy包下的注解-->
<context:component-scan base-package="com.cmy"/>
<!--配置增强类 交给Spring容器管理-->
<bean class="com.cmy.exception.ErrorLogger"></bean>
<!--开启Spring AOP注解的支持-->
<aop:aspectj-autoproxy />

 

 

编写测试用例,在DoSomeServiceImpl模拟异常

 

public class Demo2 {
    public static void main(String[] args) {
        //声明式增强 必须加载Spring容器
        ApplicationContext app = new ClassPathXmlApplicationContext("com/cmy/exception/app-08.xml");
        //获取代理对象
        DoSomeService doSomeService=(DoSomeService)app.getBean("doSomeService");
        doSomeService.say();
    }
}

 

  

 

 

4.使用注解实现最终增强

使用After包,增加切面类

 

/**
 * 通过注解实现最终增强
 */
@Aspect
public class AfterLoggerAnno {

   @After("execution(* com.cmy.service.*.*(..))")
   public void afterLogger(JoinPoint jp) {
      System.out.println(jp.getSignature().getName() + " 方法结束执行。");
   }
}

 

 

新建app-10.xml文件

 

<!--开启Spring IOC的注解支持 base-package 包扫描语句 com.cmy包下的注解-->
<context:component-scan base-package="com.cmy"></context:component-scan>
<!--配置增强类 交给Spring容器管理-->
<bean class="com.cmy.after.AfterLoggerAnno"></bean>
<!--开启Spring AOP注解的支持-->
<aop:aspectj-autoproxy />

 

 

创建测试用例

 

public class Demo2 {
    public static void main(String[] args) {
        //声明式增强 必须加载Spring容器
        ApplicationContext app = new ClassPathXmlApplicationContext("com/cmy/after/app-10.xml");
        //获取代理对象
        DoSomeService doSomeService=(DoSomeService)app.getBean("doSomeService");
        doSomeService.say();
    }
}

 

以上是关于使用注解方式实现 AOP和IoC的主要内容,如果未能解决你的问题,请参考以下文章

Java模拟Sping,实现其IOC和AOP核心

IOC和AOP注解

Spring第二天——IOC注解操作与AOP概念

面试官:谈谈你对IOC和AOP的理解

Spring第二天:Spring的IOC的注解方式Spring的AOP开发(XML)

Spring(注解+依赖注入+无配置注解+AOP)适合回顾♥♥