品牌网站建设预算,WordPress清爽主题,美术字设计,青岛李沧区城乡建设局网站文章目录 1. 实例化Bean2. 使用FactoryBean3. 依赖注入(DI)3.1 AutoWired 属性注入(查找顺序#xff1a;先类型#xff0c;后名字)3.2 AutoWired 在构造函数参数上的使用3.3 Inject和Resource 进行依赖注入3.4 Value 进行注入 1. 实例化Bean
默认使用无参构造函数… 文章目录 1. 实例化Bean2. 使用FactoryBean3. 依赖注入(DI)3.1 AutoWired 属性注入(查找顺序先类型后名字)3.2 AutoWired 在构造函数参数上的使用3.3 Inject和Resource 进行依赖注入3.4 Value 进行注入 1. 实例化Bean
默认使用无参构造函数如果在这个Bean下定义了一个有参的构造方法(没有写无参构造方法)实例化时使用的是这个有参构造方法如果有多个有参的构造方法(没有写无参构造方法)此时实例化时会报错因为不知道使用哪个构造方法。
package com.lize.demo.dao;import com.lize.demo.TestBean;
import com.lize.demo.TestBean2;
import org.springframework.stereotype.Component;Component(UserDao)
public class UserDao {private TestBean tb;private TestBean2 tb2;
// public UserDao(){
// System.out.println(构造函数);
// }public UserDao(TestBean tb){System.out.println(有参的构造函数tb);this.tb tb;}public UserDao(TestBean tb,TestBean2 tb2){System.out.println(有参的构造函数tbtb2);this.tb tb;this.tb2 tb2;}public void printUserDao(){System.out.println(UserDao);}}
package com.lize.demo;import com.lize.demo.dao.UserDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;SpringBootTest
class DemoApplicationTests {Autowiredprivate UserDao ud;Testvoid contextLoads() {ud.printUserDao();}}
报错信息如下 此时如果要实例化有参的Bean可以使用注解Bean的方式来进行如下
package com.lize.demo.dao;import com.lize.demo.TestBean;
import com.lize.demo.TestBean2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;public class UserDao {private TestBean tb;private TestBean2 tb2;public UserDao(TestBean tb){System.out.println(有参的构造函数tb);this.tb tb;}public UserDao(TestBean tb,TestBean2 tb2){System.out.println(有参的构造函数tbtb2);this.tb tb;this.tb2 tb2;}public void printUserDao(){System.out.println(UserDao);}}
package com.lize.demo.config;import com.lize.demo.TestBean;
import com.lize.demo.TestBean2;
import com.lize.demo.dao.UserDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;Configuration
public class SpringConnfig {Beanpublic UserDao getUserDao(TestBean tb,TestBean2 tb2){return new UserDao(tb,tb2);}
}
运行结果如下
2. 使用FactoryBean
定义一个类让其实现FactoryBean这个接口并重写其下方法如下
package com.lize.demo.service;import com.lize.demo.TestBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Service;Service(UserService)
public class UserService implements FactoryBean {Overridepublic Object getObject() throws Exception {return new TestBean();}Overridepublic Class? getObjectType() {return null;}
}
package com.lize.demo;import com.lize.demo.dao.UserDao;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;SpringBootApplication
public class DemoApplication {public static void main(String[] args) {ConfigurableApplicationContext context SpringApplication.run(DemoApplication.class, args);System.out.println(context.getBean(UserService));}}此时的打印结果如下 上述打印结果为TestBean而不是UserService这个Bean。如果要获取UserService这个Bean可以通过类型获取如下 还有一种做法就是在第一种的基础上通过字符串获取Bean字符串前面加上“”符号如下 如果想通过类型获取TestBean这个Bean可以在getObjectType方法下添加对应的类型信息如下 运行结果 总结一下 使用FactoryBean来实例化Bean。
FactoryBean是一个接口需要有一个Bean一旦这个Bean实现FactoryBean就成为了特殊的Bean需要实现两个方法 getObject当通过Bean实际名获取到的Bean就是getObject返回的对象伪装getObjectType想通过获取对应的类型去获取这个伪装的Bean就需要返回getObject返回的对象的类型 可以自由控制Bean的构造方法来实例化Bean
3. 依赖注入(DI)
3.1 AutoWired 属性注入(查找顺序先类型后名字)
使用这个注解首先会通过类型去容器中查找是否有这个Bean如果没有再通过名字去查找是否有这个Bean。
直接在类上添加注解Component定义Bean名字为testBean3
package com.lize.demo;import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;Component
//Primary
public class TestBean3 {private String name;public void setName(String name) {this.name name;}Overridepublic String toString() {return TestBean3{ name name \ };}
}
使用配置类定义Bean名字为TestBean31
package com.lize.demo.config;import com.lize.demo.TestBean3;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;Configuration
public class SpringConnfig {Beanpublic TestBean3 TestBean31(){return new TestBean3();}
}
上述定义了两个类型相同的Bean。
package com.lize.demo;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;Component
public class TestBean4 {Autowiredprivate TestBean3 testBean3;Overridepublic String toString() {return TestBean4{ testBean3 testBean3 };}
}在TestBean4 中引入这个Bean然后在单元测试中输出结果如下
package com.lize.demo;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;SpringBootTest
class DemoApplicationTests {Autowiredprivate TestBean4 tb4;Testvoid contextLoads() {System.out.println(tb4);}
}运行结果如下 可以看到此时因为有两个Bean类型相同因此采用名字去查找Bean在TestBean4中使用的Bean名字为testBean3因此输出的结果中的Bean为直接在类上添加注解Component的那个Beanname的值默认为空。如果把TestBean4中的那个Bean的名字修改为TestBean31那么此时的输出结果就是通过配置类定义的那个Bean了。
package com.lize.demo.config;import com.lize.demo.TestBean3;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;Configuration
public class SpringConnfig {Beanpublic TestBean3 TestBean31(){TestBean3 testBean3 new TestBean3();testBean3.setName(TestBean31);return testBean3;}}
package com.lize.demo;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;Component
public class TestBean4 {Autowiredprivate TestBean3 TestBean31;Overridepublic String toString() {return TestBean4{ testBean3 TestBean31 };}
} 如果通过名字还是查找不到比如把TestBean4中的引入那个Bean的名字修改为tb3那么此时就会报错了。
此时可以在定义Bean的那个类上添加注解 Primary表示主要的。 另外一种解决方法就是在这个TestBean4引入的那个Bean下指明到底是哪个Bean(使用注解 Qualifier)如下
3.2 AutoWired 在构造函数参数上的使用
如果一个Bean定义了多个有参的构造函数但是没有定义默认的构造函数(无参构造函数)此时在另外一个类中引入这个Bean然后在单元测试中输出这个Bean会报错如下
package com.lize.demo.dao;import com.lize.demo.TestBean;
import com.lize.demo.TestBean2;
import org.springframework.stereotype.Component;Component(UserDao)
public class UserDao {private TestBean tb;private TestBean2 tb2;
// public UserDao(){
// System.out.println(构造函数);
// }public UserDao(TestBean tb){System.out.println(有参的构造函数tb);this.tb tb;}public UserDao(TestBean tb,TestBean2 tb2){System.out.println(有参的构造函数tbtb2);this.tb tb;this.tb2 tb2;}public void printUserDao(){System.out.println(UserDao);}}如果此时想要正常输出可以在对应的构造函数上面添加注解AutoWired 如下此时正常输出。 TestBean、TestBean2如下形式 如果想要为构造函数中的参数设置为不必须的需要在参数上面设置 Autowired(required false)直接在构造函数上设置是不生效的因此会报错(下面没有给出)如下 此时打印结果为null。 另外还可以写在单元测试的方法上面如下 Spring会自动调用Autowired的方法进行自动注入在没有调用set的方法的前提下此时调用get的结果不为null如下
package com.lize.demo.dao;import com.lize.demo.TestBean;
import com.lize.demo.TestBean2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;Component(UserDao)
public class UserDao {private TestBean tb;private TestBean2 tb2;
// public UserDao(){
// System.out.println(构造函数);
// }Autowiredpublic UserDao(Autowired(required false) TestBean tb){System.out.println(有参的构造函数tb);this.tb tb;}Autowiredpublic void setTb2(TestBean2 tb2){this.tb2 tb2;}public TestBean2 getTb2(){return tb2;}public UserDao(TestBean tb,TestBean2 tb2){System.out.println(有参的构造函数tbtb2);this.tb tb;this.tb2 tb2;}public void printUserDao(){System.out.println(UserDao);}}3.3 Inject和Resource 进行依赖注入
Resource优先根据名字进行查找找不到再根据类型查找。 inject不能设置requiredfalse属性另外还需要添加额外的依赖。 推荐使用构造函数进行注入或者Resource进行注入
3.4 Value 进行注入
基本数据类型的注入
package com.lize.demo.entity;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;Component
public class User {Value(lize)private String name;Value(19)private Integer age;Overridepublic String toString() {return User{ name name \ , age age };}
}
package com.lize.demo;import com.lize.demo.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;SpringBootTest
class DemoApplicationTests {Testvoid contextLoads(Autowired User user) {System.out.println(user);}}如果想通过从文件中的数据进行注入如下新建a.properties 在Spring Boot项目中如果想获取配置文件application.properties中的数据不需要使用PropertySource指定路径文件如下 如果在数据文件获取不到对应数据在Spring Boot项目中会报错解决方法为在变量名后面加入“:”填写默认值但是在Spring中会指定把值直接注入到对应变量。 复杂数据类型的注入使用spel表达式的方式进行注入如下
package com.lize.demo.entity;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.Map;Component
public class User {Value(#{{语文:98}})private MapString,String score;Value(#{王者,原神})private ListString like_games;Overridepublic String toString() {return User{ score score , like_games like_games };}
}