spring aop底層原理ProxyFactoryBean的具體使用過程--FactoryBean深入理解
阿新 • • 發佈:2019-01-01
實際的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"));
}
}