[关闭]
@Jayfeather 2018-12-02T17:22:17.000000Z 字数 6314 阅读 844

IOC,DI,AOP例程

Spring


1. 更新记录

更新时间 更新内容
20181126 创建该笔记,实现IOC与DI功能
20181203 补充IOC,DI,AOP思维导图,更新AOP代码,部分代码添加注释
TODO 1.完善注释,思维导图
2. 继续学习数据库的运用

//你没看错,这个和上次就是同一篇文章~

2. 问题

20181203

  1. jar文件导入不完全(缺少Jar文件)
    这个问题太蠢了……就不写了……
    报错:不记得了 貌似是missingClass……
  2. AOP代理混乱(原因待查)
    报错:
    Unsatisfied dependency expressed through field 'car'; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'car' is expected to be of type 'object.Car' but was actually of type 'object.$Proxy15'

    处理:

    • Java配置:@EnableAspectJAutoProxy(proxyTargetClass = true)
    • XML配置:<aop:config proxy-target-class="true">
  3. args()导入参数问题
    问题:错误的在声明通用切点处导入参数

3. 总结

本程序实现了Spring框架的AOP和DI功能
Spring.png-128kB
------------------------------(该思维导图未完)-----------------------------
具体技术细节参见《Spring实战》在此不予赘述

4. 依赖包:

1.png-52.8kB
(导入了AOP相关包)

5. 文件目录:

2.png-9.4kB

springConfig.xml、springConfig.java为Sping的设置文件(两个文件作用一致、仅仅是两种不同的实现)

Car.java、People.java 待创建为Bean的组建类。在程序中,我们要将People类注入Car类中,实现控制反转的功能。

CarTest验证Bean是否成功创建、验证是否成功注入。

Reminding:用于AOP实验(目前只有一个环绕通知)


6. 具体代码:

springConfig.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:c="http://www.springframework.org/schema/c"
  4. xmlns:p="http://www.springframework.org/schema/p"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6. xmlns:aop="http://www.springframework.org/schema/aop"
  7. xmlns:context="http://www.springframework.org/schema/context"
  8. 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
  9. >
  10. <bean class="object.People" id="people"/>
  11. <bean class="object.Car" id="car">
  12. <constructor-arg name="people" ref="wangZiXuan"/>
  13. </bean>
  14. <!--<constructor-arg ref="people" />-->
  15. <bean class="object.Reminding" id="reminding"/>
  16. <bean class="object.WangZiXuan" id="wangZiXuan"/>
  17. <aop:config proxy-target-class="true">//<!--这是一个环绕通知-->
  18. <aop:aspect ref="reminding">
  19. <aop:pointcut id="printSpeed" expression="execution(* object.Car.printSpeed(int)) "/><!--通知通用连接点声明-->
  20. <aop:around
  21. pointcut="execution(* object.Car.printSpeed(int)) and args(maxSpeed)"
  22. method="saftyFirst"/> <!--↑和上面那个东西是等价的-->
  23. </aop:aspect>
  24. </aop:config>
  25. </beans>

springConfig.Java

  1. package object;
  2. import object.*;
  3. import org.aspectj.lang.annotation.Before;
  4. import org.springframework.beans.factory.BeanFactory;
  5. import org.springframework.beans.factory.config.ConfigurableBeanFactory;
  6. import org.springframework.context.annotation.*;
  7. import org.springframework.core.env.Environment;
  8. import org.springframework.core.type.AnnotatedTypeMetadata;
  9. import org.springframework.aop.*;
  10. @Configuration
  11. //@ComponentScans() //自动扫描并生成bean
  12. //@ComponentScan(basePackageClasses = {Car.class})
  13. @EnableAspectJAutoProxy(proxyTargetClass = true)
  14. public class springConfig {
  15. @Bean
  16. @Primary //首要注入的Bean
  17. public People peopleBean() {
  18. return new People();
  19. }
  20. @Bean
  21. @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) //限制Bean的作用域(当前为单例)
  22. public Car carBean(People people) {
  23. return new Car(people);
  24. }
  25. @Bean
  26. @Conditional(IsWangZiXuan.class) //判断是否启用Bean
  27. public WangZiXuan WangZiXuanBean() {
  28. return new WangZiXuan();
  29. }
  30. @Bean
  31. public Reminding reminding() {
  32. return new Reminding();
  33. }
  34. }
  35. class IsWangZiXuan implements Condition{
  36. //Bean判断类,要实现condition接口
  37. //还没弄懂,写个return true;先放着
  38. public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata){
  39. Environment env = context.getEnvironment();
  40. //return env.containsProperty("Car");
  41. return true;
  42. }
  43. }

Car.java

  1. package object;
  2. import org.junit.contrib.java.lang.system.SystemOutRule;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Component;
  5. @Component
  6. public class Car implements Cars {
  7. private int speed;
  8. private People people;
  9. private int maxSpeed;
  10. Car(People people){
  11. this.people=people;
  12. this.speed=people.favoriteSpeed;
  13. this.maxSpeed=120;
  14. }
  15. @Autowired
  16. public void setPeople(People people){
  17. this.people=people;
  18. speed=people.favoriteSpeed;
  19. }
  20. public void run(){
  21. this.speed=people.favoriteSpeed;
  22. }
  23. public int getSpeed(){
  24. return speed;
  25. }
  26. public void printSpeed(int maxSpeed){
  27. System.out.print(speed);
  28. }
  29. public void printFavoriteSpeed(){
  30. System.out.print(people.getFavoriteSpeed());
  31. }
  32. public int getMaxSpeed() {
  33. return maxSpeed;
  34. }
  35. }
  36. interface Cars{
  37. public void setPeople(People people);
  38. public void run();
  39. public int getSpeed();
  40. }
  41. interface Cars{
  42. public void setPeople(People people);
  43. public void run();
  44. public int getSpeed();
  45. }

People.java

  1. package object;
  2. import org.springframework.stereotype.Component;
  3. @Component
  4. public class People {
  5. int favoriteSpeed=100;
  6. public int getFavoriteSpeed() {
  7. return favoriteSpeed;
  8. }
  9. public void setFavoriteSpeed(int favoriteSpeed) {
  10. this.favoriteSpeed = favoriteSpeed;
  11. }
  12. }
  13. @Component
  14. class WangZiXuan extends People{
  15. int tall;
  16. WangZiXuan(){
  17. this.favoriteSpeed=1000;
  18. this.tall=170;
  19. }
  20. public int getTall() {
  21. return tall;
  22. }
  23. public void setTall(int tall) {
  24. this.tall = tall;
  25. }
  26. }

Reminding.java

  1. package object;
  2. import org.aspectj.lang.*;
  3. import org.aspectj.lang.annotation.Aspect;
  4. import org.aspectj.lang.annotation.Before;
  5. import org.aspectj.lang.annotation.Pointcut;
  6. import org.springframework.stereotype.Component;
  7. import org.springframework.aop.aspectj.*;
  8. @Aspect
  9. @Component
  10. public class Reminding {
  11. // @Pointcut("execution(* object.Car.printSpeed(..))")//Java配置文件的 定义切点注释
  12. // public void safty(){} //这个也是的
  13. //
  14. // @Before("safty()") //这个还是的(但是目前用的是XML 所以这个注释就没用了)
  15. public void saftyFirst(ProceedingJoinPoint JP,int maxSpeed){
  16. //环绕通知(之前写了前置和后置通知,不过被替换为更复杂的环绕通知)
  17. try {
  18. System.out.println("Safty First,Max speed is "+maxSpeed);//前置
  19. JP.proceed(); //执行的程序在这
  20. System.out.println("\nPark Car");//后置
  21. }catch (Throwable e){
  22. System.out.println("You die");//异常处理
  23. }
  24. }
  25. }

CarTest.java

  1. package object;
  2. import org.junit.Rule;
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.test.context.ContextConfiguration;
  7. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  8. import static org.junit.Assert.*;
  9. import org.junit.contrib.java.lang.system.SystemOutRule;
  10. @RunWith(SpringJUnit4ClassRunner.class)
  11. @ContextConfiguration(locations = "/config/springConfig.xml")
  12. public class CarTest {
  13. @Autowired
  14. private Car car;
  15. @Autowired
  16. private People people;
  17. @Rule
  18. public final SystemOutRule log=new SystemOutRule().enableLog();
  19. @Test
  20. public void isNOtNull(){
  21. assertNotNull(car);
  22. }
  23. @Test
  24. public void peopleIsNotNull(){
  25. assertNotNull(people);
  26. }
  27. @Test
  28. public void getMaxSpeed(){
  29. car.printSpeed();
  30. assertEquals("100",log.getLog());
  31. }
  32. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注