Spring study notes: Use annotations assembly Bean

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/sinat_38393872/article/details/100541328

This article is a summary of their own learning, Internet learning materials are lightweight Java EE development framework for the integration of SSM framework (Spring MVC + Spring + Mybatis) and Redis implementation. The author is Yangkai Zhen, Zhou Jiwen, and Tanmao Hua Liang Huahui.

This article can be viewed alone, then this article to see.

bean is a class, is not so well defined as a specific type String, Arraylist. Bean instance of a class in the storage description information (not instance), the user can get through this instance of the class method getBean Bean container belongs.

Here, bean is actually a class, this is on the Spring IoC container class. We use a simple description of the object to get information from the Spring IoC, this action is to assemble bean (the details of this part and what is the Spring Ioc container may be reading this https://blog.csdn.net/sinat_38393872/article/details / 95076976 )

 

Bean began to explain the following notes will be used to assemble a variety of annotation


@Component,@ComponentScan和@Value

By fitting @Component Bean. Use as follows.

package com.ssm.annotation;
//这两个包必须导入
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component(value = "role")       //或者写成@Component("role")
public class Role{
    @Value("1")
    private long id;
    @Value("role_name_1")    
    private String roleName;
    //setter and getter//
}

Spring IoC annotation @Componet Representative scanning will generate Bean instance of this class, the value of which is equivalent to the XML id. If you do not write the value value, the Spring default class name, id is written in lowercase.

Notes injection @Value represent a value.

With the remarks above, we have not been able to complete the assembly, because Spring IoC do not know where the scanning object, this time in addition to introducing the above-described two package code, but also need to import a PojoConfig class at the same package. PojoConfig class is shown below

package com.ssm.annotation;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan
public class PojoConfig{
}

This class is very simple, but one thing to note.

Note that the first line of code, the class name of the package and package names need to be assembled is the same class. Because @ComponentScan default scanning path of the scanning current packet, so the need to assemble and package names have the same class.

From this we can understand why the need to assemble the class dispersed in different packages, using annotations is not easy to manage, you need reasons to use XML.

 

@ComponentScan and @Component Like, @ Component parameter value may have set, @ ComponentScan also have parameters can be set. There are two parameters that can be set --basePackages and basePackateClasses

  • BasePackages value is limiting full package name, which represents Spring IoC scans all Bean class the packet assembly and all its sub-packets. such as
package com.ssm.annotation;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = {"com.ssm.eles", "com.ssm.other")}
public class PojoConfig{
}

This represents Spring IoC scans all packet classes and lower com.ssm.eles com.ssm.other (including sub-packets of all classes thereof).

  • Class is the class value basePackagesClasses class that represents Spring IoC scans these classes in the current package is assembled Bean. such as
package com.ssm.annotation;
import org.springframework.context.annotation.ComponentScan;
//Role和RoleImpl是定义好的类或接口
@ComponentScan(basePackageClasses = {Role.class, RoleImpl.class})
public class PojoConfig{
}

This represents Spring IoC Role and scans the package com.ssm.annotation RoleImpl under these two classes assembled Bean.

 

Finally, talk about issues basePackages and basePackagesClasses repeat scan.

If a plurality of corresponding packet @ComponentScan to scan, when to scan two ComponentScan same class will be arranged to generate a plurality of objects of this class.

A plurality of scans @ComponentScan same class, only configured to generate a class object.

 


@Autowired

@Autowired automatic assembly, which is to solve the problem Bean annotated assembly, and how to reference the assignment. such as

@Component("role")
public class Role {
    @Value("1")
    private int id;
    @Value("roleName1")
    private String roleName;
    @Autowired
    public Sword sword;
}

I want to assemble Role class, and the sword is value. However Sword @Value can not be assigned, so we use @Autowired comment.

After use @Autowired annotation, all the Bean will scan the container vessel, as long as the same scan Bean @Autowired a type of annotation, the Bean will be assigned to the variable @Autowired marked. For example, we have assembled a Sword class into the container, Role objects after the assembly of the code above, there is Sword value, rather than empty.

 

@Autowired attributes required

@Autowired have a property requireed. The default attribute is true, that we must find a property of the bean, you can not find the error; if the property is false, it can not find the corresponding type of Bean does not matter, does not complain. For example, the code below

@Autowired
public Sword sword;

This means that you can not find the error

@Autowired(required = false)
public Sword sword;

This means no error will not be found, which is this variable is empty.

 

@Autowired annotation method

@Autowired method can also be modified, as long as the method parameter is a reference type on the line. For example, the code below

@Autowired
public void setSword(Sword sword){
    this.sword = sword;
}

@Autowired equivalent effect found in the vessel of the same type and parameter assigned to the parameter and Bean, then execute this method.

This can also be written to find out if the container has the same type of multiple Bean, will lead to the container does not know which one to assign to the object @Autowired mark, which is the ambiguity of Autowired. For information about how to resolve the ambiguity can see this article .

 

 


@Bean

These are assembled using @Component Bean, but only @Component class annotated, a single method can not annotate. @Bean can annotate the method, and the method returns the object as Spring container Bean, such as the following code

public class Data{
    @Bean(name="dataSource")
    public Properties getDataSource(){
        Properties props = new Properties();
        props.setProperty("driver", "com.msql.jdbc.Driver");
        props.setProperty("uri", "jdbc:mysql://localhost:3306/chapter12");
        props.setProperty("username", "root");
        props.setProperty("password", "123456");
        return props;
    }
}

 

By @Bean annotation, the return value of the method is fitted getDataSource into the container, and the id of dataSource.

Use this annotation to pay attention to two points, it is to scan and @Bean data will be covered by these two @Conponent

There are two classes such as

public class Data {
    @Bean(name = "sword1")
    public Sword getSword(){
        Sword sword = new Sword();
        sword.setDamage(10);
        sword.setLength(10);
        return sword;
    }
}

@Component("sword")
public class Sword {
    @Value("1")
    private int length;
    @Value("2")
    private int damage;
    public int getLength() {
        return length;
    }
    public void setLength(int length) {
        this.length = length;
    }
    public int getDamage() {
        return damage;
    }
    public void setDamage(int damage) {
        this.damage = damage;
    }
}

Acquiring the container code here

public class AnnotationMain {
    public static void main(String[] args) {
        ApplicationContext ac = new AnnotationConfigApplicationContext(PojoConfig.class);
        Sword sword1 = (Sword) ac.getBean("sword1");
        Sword sword = (Sword) ac.getBean("sword");
        System.out.println(sword == sword1);
        System.out.println(sword.getDamage());
        System.out.println(sword1.getDamage());
    }
}

Configuration class code is as follows

@ComponentScan
public class PojoConfig {
}

Declare that more than a few classes in the same package, so do not worry scan did not sweep the problem.

But if you run AnnotationMain main method directly, in the second line will be reported NoSuchBeanDefinitionException, that is to say, sword1 @ Bean assembly could not be found. This is because the first Data Class not what annotation, to scan the container class, that class Device, so no way to look inside the skip, no assembly into the container resulting in sword1.

v There are two solutions, to add Data Class @Configuration indicates that this class need to assemble.

@Configuration
public class Data {···}

AnnotationConfigApplicationContext acquisition or use containers will be placed in the parameter Data.class

ApplicationContext ac = new AnnotationConfigApplicationContext(PojoConfig.class, Data.class);

 


@ImportResource and @Import

Both notes and annotations to solve xml hybrid assembly problems

1, assembled using annotations Xml

In some config class you may still need to use Xml to assemble Bean, this time we should use @ImportResource configuration class notes, add configuration xml inside.

I'm here with the idea and default maven project structure, as shown below

java is the project root directory. Now back @ImportResource. The annotation is added to required configuration class, code is as follows.

@ComponentScan
@ImportResource({"classpath:bean.xml"})
public class PojoConfig {
}

@ImportResource in the parameter indicates the path name, classpath project represents the root directory of the compiled (not pre-compiled). In the project idea of ​​maven, resources in the .class files and compiled in target.classes in, as shown below. We can see, bean.xml under the resources directory also placed under target.classes.

The classpath: to represent directories target.classes, so @ImportResource in the classpath: bean.xml says target.classes.bean.xml.

When we define PojoConfig container, bean.xml assembled in bean we can use.

@ImportResource can add multiple xml. such as

@ImportResource({"classpath:bean1.xml", "classpath:bean2.xml"})

This is while assembling two xml.

 

2, annotations, add another comment

A project may have multiple configuration class, we may need to configure these classes integrate, we should use this time @Import notes are used as follows.

@ComponentScan
@Import({ApplicationConfig2.class, ApplicationConfig3.class})
public class PojoConfig {
}

 

 


@PropertySource

Both annotations are used to load the properties file, use the more common scenario is to load the database. Connect the required information is stored in a database file properties, such as user names, passwords and so on. Such projects can dynamically connect to the database to get these properties.

If resources in the file jdbcConfig.properties file, as follows

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy
jdbc.username=root
jdbc.password=1234

Configuration classes with the @PropertySource annotation, it means that sends the key value loaded into the containers. Like @ImportSource @PropertySource in the meaning and properties of this article.

@ComponentScan
@PropertySource({"classpath:jdbcConfig.properties"})
public class PojoConfig {
}

Now there jdbc vessel information required to connect, then we have a jdbc class, we can use @Value ( "$ {}") assembly for the class assignment, as follows.

@Component
public class JdbcConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

@Value $ {} used to obtain the value of properties, fill braces key value can be obtained corresponding to the value.

After obtaining PojoConfig container jdbcConfig objects can be obtained.

public class AnnotationMain {
    public static void main(String[] args) {
        ApplicationContext ac = new AnnotationConfigApplicationContext(PojoConfig.class);
        JdbcConfig jdbcConfig = (JdbcConfig) ac.getBean("jdbcConfig");
        System.out.println(jdbcConfig.getPassword());
    }
}

@PropertySource plurality properties file may be loaded at the same time, written as follows

@ComponentScan
@PropertySource({"classpath:jdbcConfig.properties", "classpath:jdbcConfig1.properties"})
public class PojoConfig {
}

However, to be noted that a key issue with the cover, such as the above jdbcConfig.properties jdbcConfig1.properties and key files are the same password, and the corresponding value is not the same, as shown below

//jdbcConfig
password = 1234

//jdbcConfig1
password = 123456

When the password that is read from the container, the read value is written on the back of the properties. For example, the above

@PropertySource({"classpath:jdbcConfig.properties", "classpath:jdbcConfig1.properties"})

Read the password is jdbcConfig1 in value.

 

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/sinat_38393872/article/details/100541328