9. Lifecycle of objects managed by Spring
If you need to manage the life cycle of a Bean, you can customize the initialization and destruction methods of the life cycle in the corresponding class.
- You should use
public
Permissions; - use
void
Represents the return value type; - Method names can be customized;
- The parameter list is empty.
Such as:
package cn.tedu.spring;
public class User {
public User(a) {
System.out.println("User.User()");
}
public void init(a) {
System.out.println("User.init()");
}
public void destroy(a) {
System.out.println("User.destroy()"); }}Copy the code
In the @bean annotation for configuring Spring managed objects, configure the annotation parameters to specify that the above two methods are initialization and destruction methods respectively:
package cn.tedu.spring;
@Configuration
public class BeanFactory {
@Bean(initMethod = "init", destroyMethod = "destroy")
public User user(a) {
return newUser(); }}Copy the code
Finally, you can see:
- The initialization method is executed after the constructor and only once;
- The destruction method is executed once before the Spring container is destroyed.
10. Use component scanning to make Spring manage class objects
First, define a class (class name, package name is not required) by adding the @ComponentScan annotation before the class declaration. This annotation is used to configure the component scanning. The annotation parameter is String, representing the “scanned root package” :
package cn.tedu.spring;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan("cn.tedu.spring")
public class SpringConfig {}Copy the code
The class is declared with the @Component annotation to indicate that the class is a “Component class”. Later, when Spring scans, it automatically creates objects for all Component classes:
package cn.tedu.spring;
import org.springframework.stereotype.Component;
@Component
public class User {}Copy the code
When the SpringConfig class is loaded, the Spring framework will scan all the classes in the corresponding package and check whether they are “component classes” one by one. If they are “component classes”, they will create objects. If they are not, they will not be created.
When @ComponentScan is used, the “root package” to be scanned is configured. Suppose the “root package” to be scanned is CN.tedu. spring, it is available to configure the “cn.
Also, in the source code for the @ComponentScan annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
}
Copy the code
As you can see, the configured value can be String[], that is, multiple package names can be specified.
When using this approach, you must ensure that the class to which spring-managed objects belong has a no-argument constructor!
When using this approach, Spring defaults to using the following principles for Bean names after creating objects:
- If the first letter of the class name is uppercase and the second letter is lower case (regardless of the case of other letters), then the first letter of the class name is changed to lower case, all else unchanged, as the Bean name, for example, the class name is
User
Is the Bean nameuser
, is the name of the classUserDao
Is the Bean nameuserDao
; - If the above conditions are not met, the class name is the Bean name.
If you want to use a custom name for the Bean, you can configure parameters in the @Component annotation, for example:
package cn.tedu.spring;
import org.springframework.stereotype.Component;
@Component("uuu")
public class User {}Copy the code
A subsequent call to the getBean() method must use “uuu” as an argument to get the object!
Within the scope of the Spring framework, there are three additional annotations in addition to @Component that provide the exact equivalent effect:
@Controller
: Usually added inThe controller classBefore the statement;@Service
: Usually added inBusiness classBefore the statement;@Repository
: Usually added inClasses for the persistence layer(responsible for persistent management of data) before the declaration.
In other words, these four annotations have the same function and usage, but the semantics are different.
So far, there are two ways that the Spring framework can manage objects of a class:
- A custom method returns an object and is added before the method declaration
@Bean
Annotations; - Put the class in the package scanned by the component or its descendants and add it before the class declaration
@Component
/@Controller
/@Service
/@Repository
Annotation.
The first method above is universal, applicable to any condition, but in the design of the code is relatively troublesome, relatively inconvenient to manage; The second approach is simpler and intuitive, but only for custom classes.
So, if you write your own classes, you should do the second, and if you need Spring to manage objects from other classes (in the JDK, or in a framework), you should only do the first!
11. Use Spring to read the. Properties file
Suppose there is a jdbc.properties file under your project’s SRC /main/resources, which says:
url=jdbc:mysql://localhost:3306/db_name
driver=com.mysql.jdbc.Driver
Copy the code
Then, in the project, customize a class that declares a corresponding number of properties whose values will be the values of the above configuration information!
public class JdbcProperties {
private String url;
private String driver;
// Generate Getters & Setters for the above two attributes
}
Copy the code
When you need to read the jdbc.properties configuration file above, you need to add the @propertysource annotation before the above class declaration and configure the location of the file to read:
// The argument to the following annotation is the name of the configuration file
@PropertySource("jdbc.properties")
public class JdbcProperties {
private String url;
private String driver;
// Generate Getters & Setters for the above two attributes
}
Copy the code
Next, we can assign the read Value to two properties in the class using the @value annotation:
// The argument to the following annotation is the name of the configuration file
@PropertySource("jdbc.properties")
public class JdbcProperties {
@Value("${url}") // The value of the brace in the annotation parameter is the name to the left of the equals sign in the jdbc.properties configuration
private String url;
@Value("${driver}")
private String driver;
// Generate Getters & Setters for the above two attributes
}
Copy the code
Finally, the whole reading process is done by the Spring framework, so the above JdbcProperties class should also be managed by the Spring framework.
// The following annotation parameters specify the package to be scanned by the component. Also, make sure that the JdbcProperties class is in this package or its descendants
@ComponentScan("cn.tedu.spring")
public class SpringConfig {}Copy the code
Then, before the JdbcProperties class is declared, add the @Component annotation so that when the Spring framework scans the class, it knows “this class is a Component class” and creates objects for that class:
@Component
// The argument to the following annotation is the name of the configuration file
@PropertySource("jdbc.properties")
public class JdbcProperties {
@Value("${url}") // The value of the brace in the annotation parameter is the name to the left of the equals sign in the jdbc.properties configuration
private String url;
@Value("${driver}")
private String driver;
// Generate Getters & Setters for the above two attributes
}
Copy the code
When all is done, you can customize a class for a test run:
package cn.tedu.spring;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class SpringTests {
public static void main(String[] args) {
// 1. Load the configuration class to get the Spring container
AnnotationConfigApplicationContext ac
= new AnnotationConfigApplicationContext(SpringConfig.class);
// 2. Get the object from the Spring container
JdbcProperties jdbcProperties
= (JdbcProperties) ac.getBean("jdbcProperties");
/ / 3. Test
System.out.println(jdbcProperties.getUrl());
System.out.println(jdbcProperties.getDriver());
/ / 4. Shut downac.close(); }}Copy the code
Note: In a configuration file like jdbc.properties, if the name of a property is username and the final project is running on a Windows platform, the value read will be the name of the system user currently logged into Windows. Not the property values configured in the jdbc.properties file! Therefore, when writing jdbc.properties configuration files, it is generally recommended to add some special prefixes before each attribute so that the attribute name does not conflict with some key names, for example:
project.jdbc.url=jdbc:mysql://localhost:3399/db_name
project.jdbc.driver=com.mysql.jdbc.Driver
project.jdbc.username=root
project.jdbc.password=1234
Copy the code
Also, when using the @value annotation, configure the full name to the left of each of the above equals signs:
@Component
@PropertySource("jdbc.properties")
public class JdbcProperties {
@Value("${project.jdbc.url}")
private String url;
@Value("${project.jdbc.driver}")
private String driver;
@Value("${project.jdbc.username}")
private String username;
@Value("${project.jdbc.password}")
private String password;
// Getters & Setters
}
Copy the code
Finally, when using the Spring framework, if the value of a property is assigned by the Spring framework, the Spring framework automatically handles the conversion of data types. Therefore, when declaring a property, declare it as the desired type, for example, if it exists in a configuration file:
project.jdbc.initialSize=5
project.jdbc.maxTotal=20
Copy the code
These two attributes represent the initial number of connections and the maximum number of connections respectively, and should be numeric. When declaring an attribute in a class, you can use either int or Integer:
@Value("${project.jdbc.initialSize}")
private int initialSize;
@Value("${project.jdbc.maxTotal}")
private int maxTotal;
Copy the code
Of course, it is necessary to ensure that the conversion of the type can be successful, such as the number 5 can be converted to String, int or Integer, so the declaration of the above initialSize, these data types are available, according to the use of the needs to select!
Alternatively, there is another way to read files of type **. Properties **, which is to use the @autowired annotation to automatically assign values to properties of type Environment:
@Component
@PropertySource("jdbc.properties")
public class JdbcProperties {
@Autowired
private Environment environment;
public Environment getEnvironment(a) {
return environment;
}
public void setEnvironment(Environment environment) {
this.environment = environment; }}Copy the code
Finally, the test runs:
package cn.tedu.spring;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class SpringTests {
public static void main(String[] args) {
// 1. Load the configuration class to get the Spring container
AnnotationConfigApplicationContext ac
= new AnnotationConfigApplicationContext(SpringConfig.class);
// 2. Get the object from the Spring container
JdbcProperties jdbcProperties
= (JdbcProperties) ac.getBean("jdbcProperties");
/ / 3. Test
System.out.println(jdbcProperties.getEnvironment().getProperty("project.jdbc.url"));
System.out.println(jdbcProperties.getEnvironment().getProperty("project.jdbc.driver"));
System.out.println(jdbcProperties.getEnvironment().getProperty("project.jdbc.username"));
System.out.println(jdbcProperties.getEnvironment().getProperty("project.jdbc.password"));
System.out.println(jdbcProperties.getEnvironment().getProperty("project.jdbc.initialSize"));
System.out.println(jdbcProperties.getEnvironment().getProperty("project.jdbc.maxTotal"));
/ / 4. Shut downac.close(); }}Copy the code
As you can see, the Spring framework encapsulates all the configuration information it reads into an object of type Environment. When it needs to fetch a configuration value, it calls the getProperty() method of the Environment object. The getProperty() method returns String data. If the desired data type is not String, you need to convert it yourself!
In general, it is recommended to use the @Value annotation to read each configuration Value one by one for more flexibility.
The difference between abstract classes and interfaces
1. In common
Can contain abstract methods;
2. The difference between
- An abstract class is a “class” that is used
class
Declared as a keyword; An interface is another kind of data that is usedinterface
Declared as a keyword; - Abstract classes can have various properties with different permissions and modifiers, and can contain ordinary methods, abstract methods, or no ordinary methods at all, or no abstract methods at all. All members of the interface are
public
Of, all of the properties arestatic
,final
Before JDK 1.8, all methods were abstract; - The relationship between a common class and an abstract class is “inheritance”. When a common class inherits an abstract class, it has the obligation to rewrite the abstract method in the abstract class. In Java statements, the inheritance between classes is 1 to 1. The relationship between a common class and an interface is “implementation”. When a common class implements an interface, it is also obliged to rewrite all abstract methods in the interface. The implementation relationship between a class and an interface is 1-to-many, that is, a class can simultaneously implement several interfaces. Interfaces can also inherit from one another in a one-to-many relationship. That is, one interface can inherit from several interfaces at the same time.
3. Use experience/installation
Classes describe categories; Interface, is to describe the shape of patterns, behavior characteristics, norms, standards!
The relation between classes is A; The relationship between a class and an interface is has A.
public class Person { public String name; }
public class Student extends Person {}
public class Teacher extends Person {}
public class Animal {}public class Cat extends Animal {}
public interfacelearning{ voidTo learn (a parameter); }public interfaceteaching{}
public interfacedriving{ voidDriving (a parameter); }public class Person implementsStudy, teach, drive{} Person =newPerson(); The Person li si =new Person();
Copy the code
Attachment 1: Eclipse common shortcuts
Ctrl + Shift + F | Formatting code (code layout) |
---|---|
Ctrl + Shift + O | finishingimport Statements (add necessary, remove unnecessary) |
Alt + up/down | To move a single line of code, place the cursor on that line before operating. Move several lines of code, need to be checked before operation |
Ctrl + Alt + Direction up/Direction down | Copy several lines of code up/down in the same manner as moving the entire line |
Alt + Shift + R | To rename a variable or method in the current source file, select the entire name before performing the operation |
Ctrl + D | Deletes entire lines or lines of code in the same manner as moving entire lines of code |