实际的spring使用aop的过程,配置好ProxyFactoryBean,给ProxyFactoryBean设置一个bean id
然后通过ac.getBean(bean id),就取得被ProxyFactoryBean代理的对象,不是ProxyFactoryBean
因为这个bean id虽然代表ProxyFactoryBean对象,直接getBean获取的是ProxyFactoryBean.getObject()返回的对象,即代理对象
ac.getBean(&bean id),才能取得ProxyFactoryBean对象
【FactoryBean深入理解】
- FactoryBean,就是一个bean对象,不要被前面的Factory扰乱误导,也是要放入BeanFactory被spring管理
- FactoryBean特殊在,通过常规的ApplicationContext.getBean(beanId) 获取的不是FactoryBean这个直接对象,而是调用FactoryBean.getObject()生成的对象,返回给你
- ApplicationContext.getBean(&beanId) ,加上&才能取得FactoryBean这个对象,可以理解为c语言里的取地址的意思
- FactoryBean这样的过程,就是为了方便你定义生成【复杂bean】对象,就是这个bean对象不是简单的new ,设置几个参数,还有其他初始化才能完整被使用,比如ProxyFactoryBean
下面是直接使用main方法调用aop,帮助理解spring的aop过程,maven项目
//pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dddd</groupId>
<artifactId>spring</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<spring.version>4.3.3.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.10</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
//ServInter.java 代理接口
package com.dddd.aop;
public interface ServInter {
public void say();
}
//MyService.java 实现接口
package com.dddd.aop;
import org.springframework.stereotype.Service;
@Service
public class MyService implements ServInter {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void say() {
System.out.println("MyService say:" + name);
}
}
//MyBeforeAop.java 定义aop处理方法
package com.dddd.aop;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Component
public class MyBeforeAop implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("before aop ["+method.getName()+"] do sth...................");
}
}
//Test.java main方法测试
package com.dddd;
import com.dddd.aop.ServInter;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext("com.dddd");
//aop3 实际的spring使用aop的过程,配置好ProxyFactoryBean,给ProxyFactoryBean设置一个bean id
//然后通过ac.getBean(bean id),就取得被ProxyFactoryBean代理的对象,不是ProxyFactoryBean
//因为这个bean id虽然代表ProxyFactoryBean对象,直接getBean获取的是ProxyFactoryBean.getObject()返回的对象,即代理对象
//ac.getBean(&bean id),才能取得ProxyFactoryBean对象
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
proxyFactoryBean.setBeanFactory(ac.getBeanFactory());
//aop拦截处理类
proxyFactoryBean.setInterceptorNames("myBeforeAop");
//代理的接口
proxyFactoryBean.setInterfaces(ServInter.class);
//被代理对象
proxyFactoryBean.setTarget(ac.getBean(ServInter.class));
//放入bean工厂,实际开发是在config下使用注解,设置多个proxyFactoryBean代理,设置不同bean id
ac.getBeanFactory().registerSingleton("myproxy",proxyFactoryBean);
ServInter servInterProxy = (ServInter) ac.getBean("myproxy");
servInterProxy.say();
//获取直接的ProxyFactoryBean对象,加&
System.out.println(ac.getBean("&myproxy"));
}
}