Summary
After Spring4, the official recommended we use Java Config instead applicationContext.xml, to declare the Bean container management.
In the Spring Boot, Java Config use has also been completely replaced applicationContext.xml. Realization of a zero-configuration xml. So in terms of the evolution of Spring, or the need to learn Spring Boot, you should be in-depth study of the use of Spring Java Config. This article introduces the following aspects:
- Spring java Config entry procedures
- Use bean tag
- bean dependencies
- Auto Scan
- import and importResource
- Loading and mass properties file
- profile
Spring Java Config introductory presentation and simple procedures
Recalling the previous applicationContext.xml configuration, we will need to configure the form bean xml, then the Java Config way, do not need more thinking, we can determine that we should be in a Java bean configuration file, and the Java file should be identified Spring container. We look at the following example:
Create a bean class
public class SomeBean {
public void doWork() { System.out.println("do work..."); } }
Wherein doWork
a logical approach.
Creating a Config class
@Configuration
public class Config { @Bean public SomeBean someBean() { return new SomeBean(); } }
Note that we add on a config class @configuration
notes, see-known name meaning, we can understand the configuration class in Spring. In the return value SomeBean
of someBean
the method we add a @Bean
comment, not difficult to understand, the returned new SomeBean
objects will be submitted to the Spring container management.
test
public class Test {
public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(Config.class); SomeBean sb = context.getBean(SomeBean.class); sb.doWork(); } }
Here, we create an AnnotationConfigApplicationContext
object that passed in the Config.class
post, was SomeBean object.
do work...
These are the easiest program Spring Java Config configuration bean, do not like xml configuration developers is quite advantageous.
We know that in xml, in general, is this configuration:
<bean id="someBean" class="com.springboot.javaconfig.SomeBean" initMethod="init" destroyMethod="destroy" ref="otherBean" scope="singlon"
A complete configuration includes a bean id
, class
, initMethod
, destroyMethod
, - ref
, scope
.
So, how to configure these properties do in Java Config? Is actually very simple, we modify the first example of the code:
public class SomeBean {
private void init() { System.out.println("init..."); } public void doWork() { System.out.println("do work..."); } private void destroy() { System.out.println("destroy..."); } }
Increased init
, destroy
method.
@Configuration
public class Config { @Bean(initMethod = "init",destroyMethod = "destroy") public SomeBean someBean() { return new SomeBean(); } }
Annotation on the bean, the method name corresponding to the attribute points.
public class Test {
public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class); SomeBean sb1 = context.getBean(SomeBean.class); System.out.println(sb1); SomeBean sb2 = context.getBean(SomeBean.class); System.out.println(sb2); context.close(); } }
The output is:
init...
com.spring.SomeBean@16022d9d com.spring.SomeBean@16022d9d destroy...
From this program we can see the following information:
init
,destroy
Methods are invoked in the corresponding stage- SomeBean created two examples point to the same address, the Spring container to explain SomeBean objects we created a single case of when.
other
If you want to create more than one case of a bean, you could write:
@Scope("prototype")
public class SomeBean { }
If you want to use the id and class to find common bean, you could write:
SomeBean sb = context.getBean("someBean",SomeBean.class);
Special attention is required, Spring Config function name in the bean id as the default.
bean dependencies
In xml, we used value
to inject simple configuration values ref
to configure inject other objects, then how to achieve in Java Config well? We continue to write code:
Create a bean class
public class OtherBean {
}
Config class and modify SomeBean
public class SomeBean {
@Autowired private OtherBean otherBean; public void sayHello() { System.out.println(otherBean); } }
@Configuration
public class Config { @Bean public SomeBean someBean() { return new SomeBean; } @Bean public OtherBean otherBean () { return new OtherBean(); } }
In this case, we will OtherBean
incorporate spring containers managed, in SomeBean
a class in the OtherBean
instance implanting. got the answer:
com.spring.OtherBean@51b279c9
Thereby, a dependency injection in Java Config, but also need to rely on the bean is to join Config
the class with a bean to modify.
Of course, we can not use @AutoWired
labels, and by set
method injection.
@Configuration
public class Config { @Bean public SomeBean someBean(OtherBean otherBean) { SomeBean someBean = new SomeBean(); // 1 someBean.setOtherBean(new OtherBean()); // 2 someBean.setOtherBean(otherBean()); // 3 someBean.setOtherBean(otherBean); return someBean; } @Bean public OtherBean otherBean () { return new OtherBean(); } }
set
Injection method more, you can create a self- OtherBean
object because in Config class, or you can call the otherBean()
method can also be passed in parameter names to be used in the parameter list OtherBean
of the method name. OtherBean because there may be multiple types of objects.
Java Config configuration mix and comments
We know, such as a spring provides us @component
, @controller
, @service
, @repositroy
such labels, they increase the semantics of a class, then the class is added to the corresponding spring containers management, but also to avoid the configuration in xml. The Java Config and comments configuration mix is the way we often use in daily development, we look at the following code to simulate MVC three-tier architecture:
LoginDAO:
@Repository
public class LoginDAO { public void login() { System.out.println("login..."); } }
LoginService
@Service
public class LoginService { @Autowired private LoginDao loginDao; public void login() { loginDao.login(); } }
LoginController
@RequestMapping("/user")
@RestController
public class LoginController { @Autowired private LoginService loginService; @RequestMapping(path = "/login",method = RequestMethod.POST) public void login() { loginService.login(); } }
Java Config
@ComponentScan(basePackages = "com.spring")
@Configuration
public class Config { }
public class Test {
public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class); LoginController controller = context.getBean("loginController",LoginController.class); controller.login(); } }
Output:
login...
Interpretation: We will not LoginDAO
, LoginService
, LoginController
inclusion Config
, with @Bean
modifications, but the use of annotations configuration, Config
by class ComponentScan
labels to include them in sping container. Through testing, we found that, when feasible and annotation using Java Config mixed configuration.
Java Config and mix applicationContext.xml
Sometimes we encounter must use the xml configuration, this time, we can operate this way:
Create a file applicationContext.xml
<bean id="xmlBean" class="com.spring.XMLBean"/>
Modify Config
@ImportResource("com/spring/applicationContext.xml")
@ComponentScan(basePackages = "com.spring")
@Configuration public class Config { }
operation result:
com.spring.XMLBean@7bb58ca3
In Config
the use of the class @ImportResource
labels, can be incorporated in the xml configuration of the spring bean container.
Configuration placeholder
Custom datasource
public class DataSource {
private String url; private String driverClass; private String userName; private String password; // get() // set() // constructor() }
In xml, we configuration datasource
when the connection information is often encapsulated db.properties
in:
driverClass=com.mysql.jdbc.driver
url=jdbc:mysql://localhost:3306/my-database
username=root
password=root
Way to get use placeholder in xml:
<context:property-placeholder location="com/spring/db.properties"/>
<bean id="dataSource" class="com.spring.DataSource"> <property name="url" value="${url}"/> <property name="driverClass" value="${driverClass}"/> <property name="userName" value="${user}"/> <property name="password" value="${password}"/> </bean>
test
public class Test {
public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class); DataSource dataSource = context.getBean("dataSource",DataSource.class); System.out.println(dataSource); } }
Output:
DataSource{url='jdbc:mysql://localhost:3306/test', driverClass='com.mysql.jdbc.driver', userName='root', password='root'}
So how to interpret the placeholder in the Config configuration? Continue to write code:
To show distinction, we change it, db.properties:
driverClass=com.mysql.jdbc.driver
url=jdbc:mysql://localhost:3306/test
user=admin
password=admin
Modify Config
//@ImportResource("com/spring/applicationContext.xml")
@PropertySource("com/spring/db.properties")
@ComponentScan(basePackages = "com.spring") @Configuration public class Config { @Autowired private Environment env; @Bean public DataSource dataSource() { return new DataSource(env.getProperty("url"),env.getProperty("driverClass"), env.getProperty("user"),env.getProperty("password")); } }
At this point, we first removed the @ImportResource
label because it has no need to configure in xml, and they use a new tag @PropertySource
to load the db,properties
file, and then injected into an env
object Environment
class inherits PropertyResolver
an interface, designed to resolve properties.
Output:
DataSource{url='jdbc:mysql://localhost:3306/test', driverClass='com.mysql.jdbc.driver', user='admin', password='admin'}
We can see, loaded properties
files, in Spring Java Config also provided support.