Blog: bugstack.cn
Precipitation, share, grow, let yourself and others can gain something! 😄
One, foreword
Multithreading, locking, JVM tuning, all memorizing trouble, why the code is still messy?
Why is it that this knowledge, which is so important in books, classes, and interviews, doesn’t improve your coding skills in the real world?
First of all, these knowledge are almost not commonly used in the actual Internet business development. There are almost locking and multithreading scenarios. In order to improve performance, distributed design and implementation are basically adopted. Much of this seemingly technical knowledge is wrapped up in components of non-business logic functions that programmers rarely care about when doing business development. So it’s unlikely that learning these things will improve your code. Most of the improvements will be in finding complex bugs.
Like if you know Chinese characters, you can write poems and songs? Understand RGB can draw mountains and rivers? Can you dance and dance if you can jump? That’s not possible. Don’t think you can do martial arts just because you’re wearing kabu!
If you really want to write good code, you need to accumulate data structures and algorithmic logic (not just a few rote problems). You don’t understand why, no amount of brushing is useless), the next step is to understand design patterns and architectural design, and ultimately to continue to apply and summarize. In this process, you will come into contact with business, product and operation. Coding is only the final concrete implementation, not the most important part of the whole process. Compared with coding, logic design is more important.
2. Interview questions
Thanks for the plane, note! , this holiday a masturbation string again by Spring, hey hey, test results to interview!
Interviewer: Plane, how are you today? Have you learned everything I asked you last time?
Xie aircraft: @ Resource is JDK javax.mail. The annotation, the Resource provide annotations, ha ha ha ha ha, also studied the Bean injection.
Interviewer: I remember a little bit. Did you notice the features of Spring IOC when you were studying Bean injection? What did you use?
Xie aircraft: well, use the Bean’s configuration, BeanDefinitionRegistryPostProcessor definition of beans and FactoryBean
Interviewer: Well, alias, autowire, depends-on, factory-method, lookup-method, etc., to see how they are used.
Third, SpringIOC features
The core idea of Inversion of Control is that the use of resources is not managed by the users themselves, but by a third party that does not use the resources. In this way, resources are centrally managed, configurable and easy to maintain, and the dependence of both parties is reduced to achieve low coupling.
Back in 1988, Ralph E. Johnson & Brian Foote wrote in their paper Designing Reusable Classes
One important characteristic of a framework is that the methods defined by the user to tailor the framework will often be called from within the framework itself, rather than from the user’s application code. The framework often plays the role of the main program in coordinating and sequencing application activity. This inversion of control gives frameworks the power to serve as extensible skeletons. The methods supplied by the user tailor the generic algorithms defined in the framework for a particular application.
Here are some of the core features of IOC, as they are not only interview points, but also feature classes that need to be used when developing middleware or widgets:
1. The XML configuration
1.1 alias
The test class
public class UserService {
private UserDao userDao;
public UserService(a) {
System.out.println("I've been initialized, UserService.");
}
/ /... get/set
}
Copy the code
The XML configuration
<bean id="userService" class="org.itstack.interview.UserService"/>
<! -- Give me an individual name -->
<alias name="userService" alias="userService-alias01"/>
<! -- Aliases for aliases -->
<alias name="userService-alias01" alias="userService-alias02"/>
Copy the code
Unit testing
@Test
public void test_alias(a) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring-config-alias.xml");
logger.info("Get Bean: {}", beanFactory.getBean("userService"));
logger.info("Get Bean by alias: {}", beanFactory.getBean("userService-alias01"));
logger.info("Get Bean by alias alias: {}", beanFactory.getBean("userService-alias02"));
}
Copy the code
The test results
23:01:29.872[the main] INFO org. Itstack. Interview. Test. The ApiTest - get Bean: org. Itstack. Interview. 2 a40cd94 UserService @23:01:29.872 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'userService'
23:01:29.872[the main] INFO org. Itstack. Interview. Test. The ApiTest - get Bean by alias: org. Itstack. Interview. 2 a40cd94 UserService @23:01:29.872 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'userService'
23:01:29.872[the main] INFO org. Itstack. Interview. Test. The ApiTest - get Bean through the alias alias: org. Itstack. Interview. 2 a40cd94 UserService @Copy the code
- Purpose: Used to alias beans
- Use: In XML configuration we can give a Bean a separate name, and we can give an alias a new alias.
1.2 autowire
The test class
public class UserDao {
public UserDao(a) {
System.out.println("I've been initialized, UserDao."); }}Copy the code
The XML configuration
<bean id="userDao" class="org.itstack.interview.UserDao"/>
<! -- Manually configure dependencies -->
<bean id="userService-by-property" class="org.itstack.interview.UserService">
<property name="userDao" ref="userDao"/>
</bean>
<! -- Autoconfigure dependencies -->
<bean id="userService-by-autowire" class="org.itstack.interview.UserService" autowire="byName"/>
Copy the code
Unit testing
@Test
public void test_autowire(a) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring-config-autowire.xml");
logger.info("Get Bean by manually configuring dependencies: {}", beanFactory.getBean("userService-by-property"));
logger.info("Get Bean by auto-configuration dependency: {}", beanFactory.getBean("userService-by-autowire"));
}
Copy the code
The test results
23:05:55.501[the main] INFO org. Itstack. Interview. Test. The ApiTest - get Bean by relying on manual configuration: org. Itstack. Interview. B62af UserService @ 67923:05:55.501 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'userService-by-autowire'
23:05:55.501[the main] INFO org. Itstack. Interview. Test. The ApiTest - get Bean by automatic configuration depends on: org. Itstack. Interview. 5 cdd8682 UserService @Copy the code
- Purpose: Autowire is used to inject properties from a class into Spring management
- Use: In XML configuration, there are two ways respectively: manual configuration dependency, automatic configuration dependency, manual is very common, automatic configuration may be more for annotations. Autowire (byName, byType, constructor, etc.) ¶
1.3 the factory – method
The test class
public class StaticFactoryBean {
static public UserDao getUserDaoByStatic(a){
return newUserDao(); }}Copy the code
The XML configuration
<bean id="staticFactory-method" class="org.itstack.interview.StaticFactoryBean" factory-method="getUserDaoByStatic"/>
Copy the code
Unit testing
@Test
public void test_factory_method(a) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring-config-factory-method.xml");
logger.info("Get Bean: {}", beanFactory.getBean("staticFactory-method"));
}
Copy the code
The test results
23:15:28.950[the main] INFO org. Itstack. Interview. Test. The ApiTest - get Bean: org. Itstack. Interview. Df31b UserDao @ 58823:15:28.950 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'staticFactory-bean'
Copy the code
- Purpose: To identify the factory method of a static factory (the factory method is static)
- use: The core is the addition in XML configuration
factory-method="getUserDaoByStatic"
, so that the instantiated content of the corresponding static method can be invoked at initialization time.
1.4 the factory – bean
The test class
public class StaticFactoryBean {
public UserDao getUserDao(a){
return newUserDao(); }}Copy the code
The XML configuration
<bean id="staticFactory" class="org.itstack.interview.StaticFactoryBean"/>
<bean id="staticFactory-bean" factory-bean="staticFactory" factory-method="getUserDao"/>
Copy the code
Unit testing
@Test
public void test_factory_bean_method(a) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring-config-factory-method.xml");
logger.info("Get Bean: {}", beanFactory.getBean("staticFactory-bean"));
}
Copy the code
The test results
23:15:28.950[the main] INFO org. Itstack. Interview. Test. The ApiTest - get Bean: org. Itstack. Interview. 33 b37288 UserDao @Copy the code
- Purpose: Factory-bean, instantiating the chemical plant class
- use: factory-bean and factory-method need to be used together.
factory-method="getUserDao"
The corresponding static method is called to return the instantiation result.
1.5 the depends on
The XML configuration
<bean id="userService" class="org.itstack.interview.UserService" depends-on="userDao"/>
<bean id="userDao" class="org.itstack.interview.UserDao"/>
Copy the code
Unit testing
@Test
public void test_depends_on(a) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring-config-depends-on.xml");
logger.info("Get Bean: {}", beanFactory.getBean(UserService.class, "userService").getUserDao());
}
Copy the code
The test results
I'm being initialized, UserDao I'm being initialized, UserService23:24:14.678[the main] INFO org. Itstack. Interview. Test. The ApiTest - get Bean: org. Itstack. Interview. 45 afc369 UserDao @Copy the code
- Purpose: To deal with dependency initialization order problems
- use: If not used
depends-on="userDao"
, then the first initialization according to the Spring configuration isUserService
You need to use this configuration when you need to handle initialization dependencies.
1.6 the lookup method & ApplicationContextAware
The test class
public class UserDaoProvider implements ApplicationContextAware {
private ApplicationContext applicationContext;
public UserDao getUserDao(a) {
return applicationContext.getBean("userDao", UserDao.class);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext; }}Copy the code
The XML configuration
<bean id="userDao" class="org.itstack.interview.UserDao" scope="prototype"/>
<bean id="provider" class="org.itstack.interview.UserDaoProvider"/>
Copy the code
Unit testing
@Test
public void test_lookup_method(a) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring-config-lookup-method.xml");
logger.info("Get Bean: {}", beanFactory.getBean(UserDaoProvider.class, "provider").getUserDao());
logger.info("Get Bean: {}", beanFactory.getBean(UserDaoProvider.class, "provider").getUserDao());
}
Copy the code
The test results
I'm being initialized, UserDao16:29:25.813 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'userDao'
16:29:25.813[the main] INFO org. Itstack. Interview. Test. The ApiTest - get Bean: org. Itstack. Interview. UserDao @1188e820
16:29:25.813 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'userDao'I'm being initialized, UserDao16:29:25.814 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'userDao'
16:29:25.814[the main] INFO org. Itstack. Interview. Test. The ApiTest - get Bean: org. Itstack. Interview. 2 f490758 UserDao @Copy the code
- Purpose: To get a prototype pattern under a singleton, with new objects generated each time.
- useThe core lies in the use and usage of ApplicationContextAware
scope="prototype"
Configuration, implemented internally in Spring, uses the Cglib method, regenerates subclasses, overrides configured methods and returns objects, and achieves dynamic changes.
2. Interface classes
2.1 FactoryBean
The test class
public class MyFactoryBean implements FactoryBean<UserDao> {
@Override
public UserDao getObject(a) throws Exception {
return new UserDao();
}
@Override
publicClass<? > getObjectType() {return UserDao.class;
}
@Override
public boolean isSingleton(a) {
return true; }}Copy the code
The XML configuration
<bean id="userDao" class="org.itstack.interview.MyFactoryBean"/>
Copy the code
Unit testing
@Test
public void test_factory_bean(a) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring-config-factory-bean.xml");
logger.info("Get Bean: {}", beanFactory.getBean("userDao"));
}
Copy the code
The test results
23:36:19.339[the main] INFO org. Itstack. Interview. Test. The ApiTest - get Bean: org. Itstack. Interview. 3 bd94634 UserDao @Copy the code
- Purpose: The Bean used to generate the Bean is called a FactoryBean
- Use: This use was mentioned in the previous chapter on how beans are injected into Spring, and is used in some ORM frameworks, rPC-starter, and so on.
2.2 BeanPostProcessor
The test class
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Before initialization:" + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("After initialization:" + beanName);
returnbean; }}Copy the code
The XML configuration
<bean id="beanPostProcessor" class="org.itstack.interview.MyBeanPostProcessor"/>
<bean id="userDao" class="org.itstack.interview.UserDao"/>
Copy the code
Unit testing
@Test
public void test_bean_post_processor(a) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring-config-bean-post-processor.xml");
}
Copy the code
The test results
Before initialization: userDao After initialization: userDao16:38:32.686 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'userDao'
Copy the code
- Objective: To get the actions of the Bean object before and after initialization, and do the corresponding processing
- Use: BeanPostProcessor is an extended interface class of the Spring framework. Through the implementation of this interface, you can do related actions during Bean instantiation, such as intercepting and publishing to the registry. AOP operations are also linked to the IOC container through the BeanPostProcessor.
2.3 BeanFactoryAware
The test class
public class MyBeanFactoryAware implements BeanFactoryAware {
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {}}Copy the code
- Purpose: Used to get configuration information for the runtime Bean
- The BeanFactoryAware implementation class gets the beanFactory, which in turn gets the bean’s context information, so it’s easy to get some object properties.
Four,
- Above we have introduced the common configuration features and interfaces of Spring IOC, although you probably don’t use XML configuration objects anymore. However, there are still some common core principles behind these annotations. Only by summarizing this knowledge and learning the source code can we better understand how the use of annotations handles these configurations.
- About the use of interface classes, FactoryBean, BeanPostProcessor, BeanFactoryAware, ApplicationContextAware, are almost not available in daily business process development. But if you want to do some core component design or middleware development, it will be used very frequently. If you do not know the application of this part of knowledge, you can refer to: “SpringBoot Middleware Design and Development”
- The follow-up will be around these knowledge points to introduce some source code learning and application layer processing, Bean creation, cycle dependent three level cache solutions. I also hope that in the process of learning, we should summarize, think and record more, and build a complete knowledge stack bit by bit.
Five, series recommendation
- Sharing and analysis of meituan side
- How do I stuff a Bean into a Spring container?
- In addition to JDK and CGLIB, there are three kinds of proxy methods. The interview is stuck again!
- Half a year recruitment screening 400+ resume, tell you how to write easy to be flirted!
- SpringBoot middleware design and development