The above combs through the annotations to complete the component scanning and automatic assembly, below to learn how to use the explicit configuration of the assembly bean
Second, assemble the Bean through Java class
The Helloworldconfig class is defined earlier, and using the @componentscan and @configuration annotations, @Configuration annotations indicate that the class is a Java configuration class that is used when getting the spring application context , tell spring to create the details of the bean, through @componentscan, we enable spring's automatic component scanning, now let's see if we explicitly configure the bean through the Java class, let's practice it with a music player case.
We play music, first we need a player, then we need music resources, first we define a player interface and music resource interface
package com.seven.springTest.service;// 播放器public interface MediaPlayer { void play();}
package com.seven.springTest.service;// 音乐资源public interface MusicSource { void play();}
This time playing music we are CD-ROM to play CDs music, we will implement the above interface,
Package Com.seven.springTest.service.impl;Import org.springframework.beans.factory.annotation.Autowired;Import org.springframework.stereotype.Component;import Com.seven.springTest.service.MusicSource; import Com.seven.springTest.service.MediaPlayer; //define optical drive player public class CDPlayer implements MediaPlayer { @Autowired //Define a music resource, Here the @autowired to declare the need to inject Musicsource dependent private Musicsource cd; @Override public void Play() { //Play Music Cd.play ();}}
Implementing music resources as discs
package com.seven.springtest.service.impl;import Com.seven.springTest.service.MusicSource; public class cdsource implements MusicSource { Span class= "Hljs-keyword" >private String title = "Qi Qi Xiang"; private String artist = "Jay Chou"; @Override public void play () {System.out.println (" Playing "+ title + " by "+ Artist);}}
So far we've completed the interface definition and implementation of the player, the music resource, and what kind of dependency do we have to tell spring which beans to create? In the first part, we implicitly tell Spring through @component annotations, and now we configure the Bean component with the Java class.
@Bean
@Bean note tells the spring function to return an object that needs to be registered as a bean in the spring application context, which contains the logic that produces the bean instance
PackageCom. Seven. springtest. Configuration;ImportOrg. springframework. Context. annotation. Bean;ImportOrg. springframework. Context. annotation. Componentscan;ImportOrg. springframework. Context. annotation. Configuration;ImportCom. Seven. springtest. Service. Musicsource;ImportCom. Seven. springtest. Service. MediaPlayer;ImportCom. Seven. springtest. Service. implimport com.springtest.service.implconfigurationpublic class Medieplayerconfig {@ Bean//The Musicsource object returned by the method needs to be registered as a bean in the Spring application context Musicsource Cdsource () {new cdsource ();} @ bean//The MediaPlayer object returned by the method needs to be registered as a Bean in the Spring application context MediaPlayer CDPlayer () {return new CDPlayer ();}}
In the Medieplayerconfig class, we only added the @configuration annotations, the previous @componentscan annotations were removed, the component scans were not configured to start spring, and the implementation classes of the interfaces did not add @component annotations. We use @bean annotations to tell spring which objects need to be registered as beans in the context of the spring application. The Cdsource () method returns an instance object of type Musicsource Cdsource, which is registered to the spring application context, and the same cdplayer () The MediaPlayer method returns an instance of the type CDPlayer registered in the Spring application context. Let's test it down.
Package com.seven.springTest.main;Import Org.springframework.context.ApplicationContext;Import Org.springframework.context.annotation.AnnotationConfigApplicationContext;Import Com.seven.springTest.Configuration.MediePlayerConfig;import com.seven.springTest.Configuration.HelloWorldConfig; import com.seven.springTest.service.MediaPlayer; public class mediaplayertest {public static void Main (string[] args) {//load Java Configuration class Get Spring app context applicationcontext ac = new annotationconfigapplicationcontext (medieplayerconfig. class); //get player mediaplayer player= Ac.getbean ( mediaplayer. class); //play Player.play ();}}
When we get the player bean, we actually get the object CDPlayer returned by CDPlayer () in the Medieplayerconfig class, and in CDPlayer we rely on Musicsource, through @autowired annotations, Spring automatically injects the bean's dependency on the Musicsource, so in the test code we just get the instance player of the MediaPlayer object, and as for the player's dependencies, we don't know, it's injected by the spring container, This is just about player player, which is what spring brings to us, and we don't need to use code to manage the dependencies of objects, and all of the resources that we rely on have spring containers for us to inject.
With the development of technology, one day CD-ROM can also be inserted into the USB drive to play MP3 music, this time we come to realize a MP3 music resources
Package Com.seven.springTest.service.impl;import Com.seven.springTest.service.MusicSource; public class mp3source implements MusicSource { Span class= "Hljs-keyword" >private String title = "grandmother"; private String artist = "Jay Chou"; @Override public void play () {//TODO auto-generated method Stub System.out.println ( "MP3 Playing" + title + " by "+ Artist)}}
In the first part of automatic assembly, if spring finds that more than one bean satisfies the dependency, spring cannot choose, so if we define the implementation of the Mp3source, will this happen now? By running the program, we find that there is no effect on whether the CDPlayer bean is injected with musicsource dependency or cdsource. This is because we have told the spring-generated bean implementation logic in Medieplayerconfig by Cdsource (), so let's modify the next Cdsource ()
@Bean //该方法返回的MusicSource对象需要注册为Spring应用上下文中的beanpublic MusicSource cdsource(){ //返回MP3Source实例 return new MP3Source();}
We then run the test method, found that the output has become "==mp3 Playing grandmother by Jay Chou = =", the injection of dependent object implementation has changed, because Cdsource () is implemented in the return Mp3source instance.
As with previous @component, the Bean returned by the method that added the @bean annotation is also assigned an ID by default, with the same method name by default, such as the ID of the bean returned by the Cdsource () method as "Cdsource", and we can also specify the bean's ID. As follows:
@Bean(name="myCdplayer") //该方法返回的MediaPlayer对象需要注册为Spring应用上下文中的beanpublic MediaPlayer cdplayer(){ return new CDPlayer();}
This allows the bean to be retrieved by ID when it gets
public class MediaPlayerTest { public static void main(String[] args) { //加载java配置类获取Spring应用上下文 ApplicationContext ac = new AnnotationConfigApplicationContext(MediePlayerConfig.class); //根据ID获取bean MediaPlayer player= (MediaPlayer) ac.getBean("myCdplayer"); //播放 player.play(); }}
In the above case, the CDPlayer bean is dependent on musicsource, and we declare the dependency of CDPlayer through @autowired in the CDPlayer class, which is also an implicit configuration through annotations. Let's do this with the Java configuration class.
In the case of an explicit configuration, because the bean configured in Medieplayerconfig is returned through a method, it needs to inject a dependency into the method that returns the object bean:
@Bean(name="myCdplayer") //该方法返回的MediaPlayer对象需要注册为Spring应用上下文中的beanpublic MediaPlayer cdplayer(){ return new CDPlayer(cdsource()); //通过对象的构造函数注入依赖}
Or
@Bean(name="myCdplayer") //该方法返回的MediaPlayer对象需要注册为Spring应用上下文中的beanpublic MediaPlayer cdplayer(MusicSource musicSource){ return new CDPlayer(musicSource); //通过对象的构造函数注入依赖}
With the above 2 configuration, spring can complete the dependency injection on the Musicsource object in CDPlayer, and we define a bean configuration
@Bean(name="myCdplayer") //该方法返回的MediaPlayer对象需要注册为Spring应用上下文中的beanpublic MediaPlayer cdplayer(){ return new CDPlayer(cdsource()); //通过对象的构造函数注入依赖}@Bean(name="otherCdplayer") //定义另外一个bean对象,public MediaPlayer othercdplayer(){ return new CDPlayer(cdsource());}
MediaPlayer interface adds a way to get playback resources
package com.seven.springTest.service;public interface MediaPlayer { /** * 获取播放器加载的资源 * @return MusicSource */ MusicSource getResource(); /** * 播放 */ void play();}
To solve the following, we modify the test code
Package com.seven.springTest.main;Import Org.springframework.context.ApplicationContext;Import Org.springframework.context.annotation.AnnotationConfigApplicationContext;Import Com.seven.springTest.Configuration.MediePlayerConfig;Import Com.seven.springTest.Configuration.HelloWorldConfig;Import Com.seven.springTest.service.MediaPlayer;PublicClassmediaplayertest {Publicstatic void Main (String[] (args) {//load Java Configuration class Get Spring app context applicationcontext ac = new annotationconfigapplicationcontext (medieplayerconfig. Class); //get player mediaplayer player = ( "Mycdplayer"); mediaplayer Otherplayer = (mediaplayer) Ac.getBean (" Othercdplayer "); if (Player.getresource (). Equals (Otherplayer.getresource ())) {println ( "true");} //play //player.play ();}}
After running, we find the output "true", which shows what the situation is, we are in the CDPlayer () and Othercdplayer () method when invoking the CDPlayer (Cdsource ()) construct, by Cdsource () Gets the music resource object is the same, by default, the Bean in spring is singleton, spring intercepts the call to Cdsource (), and ensures that the spring-created Bean is returned, that is, spring itself calls Cdsource the first time ( ) created by the Bean.
Assembling beans through Java code