The first thing to know is the difference between BeanFactory and FactoryBean. The names are similar, so it’s easy to get confused.
BeanFactory: Ends with Factory, indicating that it is a Factory class that is used to manage beans.
FactoryBean: End with Bean to indicate that it is a Bean. Unlike a regular Bean, it is a Bean that implements the FactoryBean<T> interface. According to the Bean’s Id, the BeanFactory is actually the object returned by getObject() of FactoryBean. Instead of the FactoryBean itself, if you want to get a FactoryBean object, you can get it by adding an ampersand to the id.
Plain bean configuration:
<bean id="personService" class="com.spring.service.impl.PersonServiceImpl" scope="prototype">
<property name="name" value="is_zhoufeng" />
</bean>
Copy the code
So when you use BeanFactory to get the bean from the ID personService, the object you get is PersonServiceImpl
The FactoryBean configuration, using ProxyFactoryBean provided by Spring as an example, is as follows:
<bean id="personServiceByLog" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>com.spring.service.PersonService</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>logInteceptor</value>
<value>ZFMethodAdvice</value>
</list>
</property>
<property name="targetName" value="personService" />
</bean>
Copy the code
The Bean retrieved from the personServiceByLog in the code is actually of type PersonService.
test:
@Test
public void test01(a) {
PersonService ps = context.getBean("personServiceByLog", PersonService.class);
ps.sayHello();
String name = ps.getName();
System.out.println(name);
}
Copy the code
To get the ProxyFactoryBean itself, do the following
@Test
public void test04(a) {
ProxyFactoryBean factoryBean = context.getBean("&personServiceByLog", ProxyFactoryBean.class);
PersonService ps = (PersonService) factoryBean.getObject();
String name = ps.getName();
System.out.println(name);
}
Copy the code
A FactoryBean is a proxy for an object, intercepts all methods of the object, and outputs a log line before and after the method call
package com.spring.factorybean;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
public class ZFFactoryBean implements FactoryBean<Object>, InitializingBean.DisposableBean {
// The name of the interface implemented by the Proxy object (used when using Proxy to determine the type of Proxy object to be generated)
private String interfaceName;
// The proxied object
private Object target;
// Generated proxy object
private Object proxyObj;
public void destroy(a) throws Exception {
System.out.println("distory...");
}
public void afterPropertiesSet(a) throws Exception {
proxyObj = Proxy.newProxyInstance(this.getClass().getClassLoader(),
new Class[] { Class.forName(interfaceName) }, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("method:" + method.getName());
System.out.println("Method before...");
Object result = method.invoke(target, args);
System.out.println("Method after...");
returnresult; }}); System.out.println("afterPropertiesSet");
}
public Object getObject(a) throws Exception {
System.out.println("getObject");
return proxyObj;
}
publicClass<? > getObjectType() {return proxyObj == null ? Object.class : proxyObj.getClass();
}
public boolean isSingleton(a) {
return true;
}
public String getInterfaceName(a) {
return interfaceName;
}
public void setInterfaceName(String interfaceName) {
this.interfaceName = interfaceName;
}
public Object getTarget(a) {
return target;
}
public void setTarget(Object target) {
this.target = target; }}Copy the code
Let’s try, first defining the bean like this
<bean id="personService" class="com.spring.service.impl.PersonServiceImpl" scope="prototype">
<property name="name" value="is_zhoufeng" />
</bean>
<bean id="zfPersonService" class="com.spring.factorybean.ZFFactoryBean">
<property name="interfaceName" value="com.spring.service.PersonService" />
<property name="target" ref="personService"/>
</bean>
Copy the code
Then get the Bean and test it.
@Test
public void test06(a) {
PersonService ps = context.getBean("zfPersonService", PersonService.class);
ps.sayHello();
String name = ps.getName();
System.out.println(name);
}
Copy the code
You’ll see log prints before and after sayHello and getName calls.
The ZFBeanFactory above is just an implementation that mimics the functionality of ProxyFactoryBean. There are many useful functions that can be implemented through factoryBeans.
This article is reprinted from blog.csdn.net/is_zhoufeng…