第一章:环境搭建
- IDEA 2021+。
- JDK 11+。
Maven 3.8。
pom.xml
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.12</version>
</dependency>
<!-- junit单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
第二章:根据类型获取 bean
2.1 情景一
- bean 对应的类没有实现任何接口,根据 bean 本身的类型获取 bean。
- ① 如果 IOC 容器中同类型的 bean 只有一个,那么可以根据 bean 本身的类型可以获取 bean 。
② 如果 IOC 容器中同类型的 bean 不止一个,那么根据 bean 本身的类型获取 bean ,会抛出
NoUniqueBeanDefinitionException
异常。示例:
- Hello.java
package com.github.fairy.era.bean;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 07:56
*/
public class Hello {
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="hello" class="com.github.fairy.era.bean.Hello"></bean>
</beans>
- 测试:
package com.github.fairy.era.bean;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
public class SpringTest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Hello hello = context.getBean(Hello.class);
System.out.println("hello = " + hello);
}
}
- 结果:
hello = com.github.fairy.era.bean.Hello@1c7696c6
- 示例:
- Hello.java
package com.github.fairy.era.bean;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 07:56
*/
public class Hello {
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="hello" class="com.github.fairy.era.bean.Hello"></bean>
<bean id="hello2" class="com.github.fairy.era.bean.Hello"></bean>
</beans>
- 测试:
package com.github.fairy.era.bean;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
public class SpringTest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Hello hello = context.getBean(Hello.class);
System.out.println("hello = " + hello);
}
}
- 结果:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.github.fairy.era.bean.Hello' available: expected single matching bean but found 2: hello,hello2
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1262)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:494)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:349)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1172)
at com.github.fairy.era.bean.SpringTest.test(SpringTest.java:19)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
2.2 情景二
- bean 对应的类实现了接口,这个接口也只有一个实现类。
- ① 根据接口类型可以获取到 bean 。
- ② 根据实现类的类型可以获取到 bean 。
③ 上面两种情况下,获取的 bean 是同一个对象。
示例:
- Happy.java
package com.github.fairy.era.bean;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:05
*/
public interface Happy {
}
- HappyImpl.java
package com.github.fairy.era.bean.impl;
import com.github.fairy.era.bean.Happy;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:05
*/
public class HappyImpl implements Happy {
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="happy" class="com.github.fairy.era.bean.impl.HappyImpl"></bean>
</beans>
- 测试:
package com.github.fairy.era.bean;
import com.github.fairy.era.bean.impl.HappyImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
public class SpringTest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Happy happyImpl = context.getBean(HappyImpl.class);
System.out.println("happyImpl = " + happyImpl);
Happy happy = context.getBean(Happy.class);
System.out.println("happy = " + happy);
System.out.println(happy == happyImpl);
}
}
- 结果:
happyImpl = com.github.fairy.era.bean.impl.HappyImpl@6574a52c
happy = com.github.fairy.era.bean.impl.HappyImpl@6574a52c
true
2.3 情景三
- 声明一个接口,接口有多个实现类,并且这多个实现类都放入到了 IOC 容器中。
- ① 根据接口类型获取 bean ,会抛出
NoUniqueBeanDefinitionException
异常。 ② 根据实现类的类型可以正常获取到 bean 。
示例:根据实现类的类型获取bean
- Happy.java
package com.github.fairy.era.bean;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:05
*/
public interface Happy {
}
- HappyImpl.java
package com.github.fairy.era.bean.impl;
import com.github.fairy.era.bean.Happy;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:05
*/
public class HappyImpl implements Happy {
}
- HappyImpl2.java
package com.github.fairy.era.bean.impl;
import com.github.fairy.era.bean.Happy;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:05
*/
public class HappyImpl2 implements Happy {
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="happy" class="com.github.fairy.era.bean.impl.HappyImpl"></bean>
<bean id="happy2" class="com.github.fairy.era.bean.impl.HappyImpl2"></bean>
</beans>
- 测试:
package com.github.fairy.era.bean;
import com.github.fairy.era.bean.impl.HappyImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
public class SpringTest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Happy happyImpl = context.getBean(HappyImpl.class);
System.out.println("happyImpl = " + happyImpl);
}
}
- 结果:
happyImpl = com.github.fairy.era.bean.impl.HappyImpl@6c1a5b54
- 示例:根据接口类型获取bean
- Happy.java
package com.github.fairy.era.bean;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:05
*/
public interface Happy {
}
- HappyImpl.java
package com.github.fairy.era.bean.impl;
import com.github.fairy.era.bean.Happy;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:05
*/
public class HappyImpl implements Happy {
}
- HappyImpl2.java
package com.github.fairy.era.bean.impl;
import com.github.fairy.era.bean.Happy;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:05
*/
public class HappyImpl2 implements Happy {
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="happy" class="com.github.fairy.era.bean.impl.HappyImpl"></bean>
<bean id="happy2" class="com.github.fairy.era.bean.impl.HappyImpl2"></bean>
</beans>
- 测试:
package com.github.fairy.era.bean;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
public class SpringTest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Happy happy = context.getBean(Happy.class);
System.out.println("happy = " + happy);
}
}
- 结果:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.github.fairy.era.bean.Happy' available: expected single matching bean but found 2: happy,happy2
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1262)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:494)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:349)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1172)
at com.github.fairy.era.bean.SpringTest.test(SpringTest.java:22)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
2.4 情景四
- 声明一个接口,接口有一个实现类,创建一个切面类,对上面接口中的实现类应用通知。
- ① 根据接口类型获取可以获取到 bean 。
② 根据实现类的类型不能获取到 bean ,因为应用了切面之后,真正放到 IOC 容器中的是代理类的对象,而不是目标类的对象。
示例:根据接口类型获取获取 bean
- Happy.java
package com.github.fairy.era.bean;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:05
*/
public interface Happy {
void add();
void sub();
void mul();
void div();
}
- HappyImpl.java
package com.github.fairy.era.bean.impl;
import com.github.fairy.era.bean.Happy;
import org.springframework.stereotype.Component;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:05
*/
@Component
public class HappyImpl implements Happy {
@Override
public void add() {
System.out.println("add方法");
}
@Override
public void sub() {
System.out.println("sub方法");
}
@Override
public void mul() {
System.out.println("mul方法");
}
@Override
public void div() {
System.out.println("div方法");
}
}
- LogAspect.java
package com.github.fairy.era.bean.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:24
*/
@Aspect
@Component
public class LogAspect {
@Before("execution(* *..*.*(..))")
public void printBeforeLog() {
System.out.println("前置通知");
}
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.github.fairy.era"></context:component-scan>
<!-- 开启AOP的注解支持 -->
<aop:aspectj-autoproxy/>
</beans>
- 测试:
package com.github.fairy.era.bean;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
public class SpringTest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Happy happy = context.getBean(Happy.class);
happy.add();
}
}
- 结果:
前置通知
add方法
- 示例:根据实现类获取 bean
- Happy.java
package com.github.fairy.era.bean;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:05
*/
public interface Happy {
void add();
void sub();
void mul();
void div();
}
- HappyImpl.java
package com.github.fairy.era.bean.impl;
import com.github.fairy.era.bean.Happy;
import org.springframework.stereotype.Component;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:05
*/
@Component
public class HappyImpl implements Happy {
@Override
public void add() {
System.out.println("add方法");
}
@Override
public void sub() {
System.out.println("sub方法");
}
@Override
public void mul() {
System.out.println("mul方法");
}
@Override
public void div() {
System.out.println("div方法");
}
}
- LogAspect.java
package com.github.fairy.era.bean.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:24
*/
@Aspect
@Component
public class LogAspect {
@Before("execution(* *..*.*(..))")
public void printBeforeLog() {
System.out.println("前置通知");
}
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.github.fairy.era"></context:component-scan>
<!-- 开启AOP的注解支持 -->
<aop:aspectj-autoproxy/>
</beans>
- 测试:
package com.github.fairy.era.bean;
import com.github.fairy.era.bean.impl.HappyImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
public class SpringTest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Happy happy = context.getBean(HappyImpl.class);
happy.add();
}
}
- 结果:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.github.fairy.era.bean.impl.HappyImpl' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1172)
at com.github.fairy.era.bean.SpringTest.test(SpringTest.java:20)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
2.5 情景五
- 声明一个类,创建一个切面类,对这个类应用通知,根据类的类型可以获取到 bean 。
- 示例:
- StudentService.java
package com.github.fairy.era.bean.service;
import org.springframework.stereotype.Service;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:53
*/
@Service
public class StudentService {
public void getMessage() {
System.out.println("getMessage");
}
}
- LogAspect.java
package com.github.fairy.era.bean.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:24
*/
@Aspect
@Component
public class LogAspect {
@Before("execution(* *..*.*(..))")
public void printBeforeLog() {
System.out.println("前置通知");
}
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.github.fairy.era"></context:component-scan>
<!-- 开启AOP的注解支持 -->
<aop:aspectj-autoproxy/>
</beans>
- 测试:
package com.github.fairy.era.bean;
import com.github.fairy.era.bean.service.StudentService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
public class SpringTest {
@Test
public void test() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
StudentService studentService = context.getBean(StudentService.class);
studentService.getMessage();
}
}
- 结果:
前置通知
getMessage
第三章:自动装配
3.1 概述
- 自动装配需要先从 IOC 容器中获取到唯一的一个 bean 才能够执行装配,所以装配是否成功和装配底层的原理和钱测试的获取 bean 的机制是一致的。
3.2 情景一
- bean 对应的类没有实现任何接口,根据 bean 本身的类型装配这个 bean 。
- ① 如果 IOC 容器中同类型的 bean 只有一个,那么正常装配。
② 如果 IOC 容器中同类型的 bean 不止一个,那么
@Autowired
注解会根据 bean 的 id 和属性名匹配,如果匹配成功,那么就注入,否则抛出NoUniqueBeanDefinitionException
异常。示例:IOC 容器中同类型的 bean 只有一个
- Hello.java
package com.github.fairy.era.bean;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:24
*/
public class Hello {
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="hello" class="com.github.fairy.era.bean.Hello"/>
</beans>
- 测试:
package com.github.fairy.era.bean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(value = {"classpath:applicationContext.xml"})
public class SpringTest {
@Autowired
private Hello hello;
@Test
public void test() {
System.out.println("hello = " + hello);
}
}
- 结果:
hello = com.github.fairy.era.bean.Hello@1722011b
- 示例:IOC 容器中同类型的 bean 不止一个
- Hello.java
package com.github.fairy.era.bean;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:24
*/
public class Hello {
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="hello" class="com.github.fairy.era.bean.Hello"/>
<bean id="hello2" class="com.github.fairy.era.bean.Hello"/>
</beans>
- 测试:
package com.github.fairy.era.bean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(value = {"classpath:applicationContext.xml"})
public class SpringTest {
@Autowired
private Hello hello3;
@Test
public void test() {
System.out.println("hello = " + hello3);
}
}
- 结果:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.github.fairy.era.bean.SpringTest': Unsatisfied dependency expressed through field 'hello3'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.github.fairy.era.bean.Hello' available: expected single matching bean but found 2: hello,hello2
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:659)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:639)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:417)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:119)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.github.fairy.era.bean.Hello' available: expected single matching bean but found 2: hello,hello2
at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:220)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1358)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:656)
... 29 more
3.3 情景二
- 目标 bean 对应的类实现了接口,这个接口也只有这一个实现类。
- ① 根据接口类型装配 bean ,成功。
② 根据实现类的类型装配 bean ,成功。
示例:根据接口类型装配 bean
- Happy.java
package com.github.fairy.era.bean;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:51
*/
public interface Happy {
}
- HappyImpl.java
package com.github.fairy.era.bean.impl;
import com.github.fairy.era.bean.Happy;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:51
*/
public class HappyImpl implements Happy {
}
- applicatoinContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="happy" class="com.github.fairy.era.bean.impl.HappyImpl"></bean>
</beans>
- 测试:
package com.github.fairy.era.bean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(value = {"classpath:applicationContext.xml"})
public class SpringTest {
@Autowired
private Happy happy;
@Test
public void test() {
System.out.println("happy = " + happy);
}
}
- 结果:
happy = com.github.fairy.era.bean.impl.HappyImpl@57ad2aa7
- 示例:根据实现类类型装配 bean
- Happy.java
package com.github.fairy.era.bean;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:51
*/
public interface Happy {
}
- HappyImpl.java
package com.github.fairy.era.bean.impl;
import com.github.fairy.era.bean.Happy;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:51
*/
public class HappyImpl implements Happy {
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="happy" class="com.github.fairy.era.bean.impl.HappyImpl"></bean>
</beans>
- 测试:
package com.github.fairy.era.bean;
import com.github.fairy.era.bean.impl.HappyImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(value = {"classpath:applicationContext.xml"})
public class SpringTest {
@Autowired
private HappyImpl happyImpl;
@Test
public void test() {
System.out.println("happyImpl = " + happyImpl);
}
}
- 结果:
happyImpl = com.github.fairy.era.bean.impl.HappyImpl@57ad2aa7
3.4 情景三
- 声明一个接口,该接口有多个实现类,并且这多个实现类都放入到IOC容器中。
- ① 根据接口类型装配 bean ,
@Autowired
注解会先根据类型查找,此时会找到多个符合的 bean ,然后根据成员变量名作为 bean 的 id 进一步筛选,如果没有id匹配的,则会抛出NoUniqueBeanDefinitionException
异常,表示 IOC 容器中这个类型的 bean 有多个。 ② 根据实现类的类型装配 bean,成功。
示例:根据实现类的类型装配 bean
- Happy.java
package com.github.fairy.era.bean;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:51
*/
public interface Happy {
}
- HappyImpl.java
package com.github.fairy.era.bean.impl;
import com.github.fairy.era.bean.Happy;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:51
*/
public class HappyImpl implements Happy {
}
- HappyImpl2.java
package com.github.fairy.era.bean.impl;
import com.github.fairy.era.bean.Happy;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:51
*/
public class HappyImpl2 implements Happy {
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="happy" class="com.github.fairy.era.bean.impl.HappyImpl"></bean>
<bean id="happy2" class="com.github.fairy.era.bean.impl.HappyImpl2"></bean>
</beans>
- 测试:
package com.github.fairy.era.bean;
import com.github.fairy.era.bean.impl.HappyImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(value = {"classpath:applicationContext.xml"})
public class SpringTest {
@Autowired
private HappyImpl happyImpl;
@Test
public void test() {
System.out.println("happyImpl = " + happyImpl);
}
}
- 结果:
happyImpl = com.github.fairy.era.bean.impl.HappyImpl@5b3f61ff
- 示例:根据接口类型装配 bean
- Happy.java
package com.github.fairy.era.bean;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:51
*/
public interface Happy {
}
- HappyImpl.java
package com.github.fairy.era.bean.impl;
import com.github.fairy.era.bean.Happy;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:51
*/
public class HappyImpl implements Happy {
}
- HappyImpl2.java
package com.github.fairy.era.bean.impl;
import com.github.fairy.era.bean.Happy;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:51
*/
public class HappyImpl2 implements Happy {
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="happy" class="com.github.fairy.era.bean.impl.HappyImpl"></bean>
<bean id="happy2" class="com.github.fairy.era.bean.impl.HappyImpl2"></bean>
</beans>
- 测试:
package com.github.fairy.era.bean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(value = {"classpath:applicationContext.xml"})
public class SpringTest {
@Autowired
private Happy happy;
@Test
public void test() {
System.out.println("happy = " + happy);
}
}
- 结果:
happy = com.github.fairy.era.bean.impl.HappyImpl@5b3f61ff
3.5 情景四
- 声明一个接口,该接口有一个实现类,创建一个切面类,对实现类应用通知。
- ① 根据接口类型装配 bean,成功。
② 根据实现类的类型装配 bean,会抛出
BeanNotOfRequiredTypeException
异常。示例:根据接口类型装配 bean
- Happy.java
package com.github.fairy.era.bean;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:51
*/
public interface Happy {
void add();
void sub();
void mul();
void div();
}
- HappyImpl.java
package com.github.fairy.era.bean.impl;
import com.github.fairy.era.bean.Happy;
import org.springframework.stereotype.Component;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:51
*/
@Component
public class HappyImpl implements Happy {
@Override
public void add() {
System.out.println("add方法");
}
@Override
public void sub() {
System.out.println("sub方法");
}
@Override
public void mul() {
System.out.println("mul方法");
}
@Override
public void div() {
System.out.println("div方法");
}
}
- LogAspect.java
package com.github.fairy.era.bean.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:24
*/
@Aspect
@Component
public class LogAspect {
@Before("execution(* *..*.*(..))")
public void printBeforeLog() {
System.out.println("前置通知");
}
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.github.fairy.era"></context:component-scan>
<!-- 开启AOP的注解支持 -->
<aop:aspectj-autoproxy/>
</beans>
- 测试:
package com.github.fairy.era.bean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(value = {"classpath:applicationContext.xml"})
public class SpringTest {
@Autowired
private Happy happy;
@Test
public void test() {
System.out.println("happy = " + happy);
}
}
- 结果:
前置通知
happy = com.github.fairy.era.bean.impl.HappyImpl@192d74fb
- 示例:根据实现类的类型装配 bean
- Happy.java
package com.github.fairy.era.bean;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:51
*/
public interface Happy {
void add();
void sub();
void mul();
void div();
}
- HappyImpl.java
package com.github.fairy.era.bean.impl;
import com.github.fairy.era.bean.Happy;
import org.springframework.stereotype.Component;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:51
*/
@Component
public class HappyImpl implements Happy {
@Override
public void add() {
System.out.println("add方法");
}
@Override
public void sub() {
System.out.println("sub方法");
}
@Override
public void mul() {
System.out.println("mul方法");
}
@Override
public void div() {
System.out.println("div方法");
}
}
- LogAspect.java
package com.github.fairy.era.bean.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:24
*/
@Aspect
@Component
public class LogAspect {
@Before("execution(* *..*.*(..))")
public void printBeforeLog() {
System.out.println("前置通知");
}
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.github.fairy.era"></context:component-scan>
<!-- 开启AOP的注解支持 -->
<aop:aspectj-autoproxy/>
</beans>
- 测试:
package com.github.fairy.era.bean;
import com.github.fairy.era.bean.impl.HappyImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(value = {"classpath:applicationContext.xml"})
public class SpringTest {
@Autowired
private HappyImpl happyImpl;
@Test
public void test() {
System.out.println("happyImpl = " + happyImpl);
}
}
- 结果:
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'happyImpl' is expected to be of type 'com.github.fairy.era.bean.impl.HappyImpl' but was actually of type 'com.sun.proxy.$Proxy21'
at org.springframework.beans.factory.support.DefaultListableBeanFactory.checkBeanNotOfRequiredType(DefaultListableBeanFactory.java:1809)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1786)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1346)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:656)
... 29 more
3.6 情景五
声明一个类,创建一个切面类,对这个类中应用通知,根据类装配 bean ,成功。
示例:
- Happy.java
package com.github.fairy.era.bean;
import org.springframework.stereotype.Component;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 09:51
*/
@Component
public class Happy {
public void add() {
System.out.println("add方法");
}
public void sub() {
System.out.println("sub方法");
}
public void mul() {
System.out.println("mul方法");
}
public void div() {
System.out.println("div方法");
}
}
- LogAspect.java
package com.github.fairy.era.bean.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-09 08:24
*/
@Aspect
@Component
public class LogAspect {
@Before("execution(* *..*.*(..))")
public void printBeforeLog() {
System.out.println("前置通知");
}
}
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.github.fairy.era"></context:component-scan>
<!-- 开启AOP的注解支持 -->
<aop:aspectj-autoproxy/>
</beans>
- 测试:
package com.github.fairy.era.bean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-05 11:02
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(value = {"classpath:applicationContext.xml"})
public class SpringTest {
@Autowired
private Happy happy;
@Test
public void test() {
System.out.println("happy = " + happy);
}
}
- 结果:
前置通知
happy = com.github.fairy.era.bean.Happy@63c5efee