spring依赖注入

2023-05-16

目录

1、使用bean标签注入

1、pom.xml文件配置

2、spring配置文件(存放bean、spring注解等相关信息的文件)

3、bean标签生成对象

4、对象的依赖注入

(1)、通过set方法:

(2)通过构造方法注入(有参构造)。

5、普通数据类型、集合的依赖注入

2、原始注解

 1、@Repository

2、@Service("userService")

3、注入对象属性

3、@Autowired+@Qualifier=@Resource

3.1@Resource

3.2@Autowired

3.3@Qualifier

4、注入普通属性

5、新注解

 5.1@Configuration、@ComponentScan、@Import

5.2@PropertySource、@Bean


1、使用bean标签注入

1、pom.xml文件配置

在maven项目中的pom.xml文件中配置spring依赖:

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.6.RELEASE</version>
    </dependency>

2、spring配置文件(存放bean、spring注解等相关信息的文件)

创建spring的配置文件(pom.xml配置了spring以来后可以直接生成spring的配置文件)applicationContext.xml。

3、编写对应的接口(userDao、userService)和实现类(DaoImpl、ServiceImpl)。在实现类中复写接口的方法。

3、bean标签生成对象

在spring的配置文件applicationContext.xml中创建bean标签,让spring来生成对象:

<bean id="userDao" class="com.gdut.depen.Dao.Impl.DaoImpl">

这里的Id属性是bean标签的唯一属性不可重复,对应了一个具体的对象,例如在程序中连续使用两次getBeam("userDao"),返回的是一样的地址。class属性是对应实现类的全类名,这里用了反射机制在spring中生成DaoImpl对象。

4、对象的依赖注入

为什么要依赖注入。在使用spring的依赖注入之前,虽然已经有各种各样的对象存在于spring容器中,但是如果一个对象要调用另一个对象的方法还需要再Java代码中创建一个applicationcontext对象并使用getbean()来获得另一个类,如果可以再spring容器中就可以让一个类获得了另一个类的对象就会方便很多

将userDao注入userService有两个方法:构造方法、set方法。这样子就可以在spring中直接将userDao对象注入到userService对象中,不需要在ServiceImpl中通过以下代码来获取userDao对象

ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
userDao userDao = app.getBean("userDao");
userDao.save();

(1)、通过set方法:

在类中建一个成员属性,并为其创建set方法:

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
                this.userDao = userDao  
        }

接着在xml配置文件中的serviceDao对应的bean标签里面注入userDao对象

    <bean id="serviceDao" class="com.gdut.depen.Service.Impl.serviceImpl">
        <property name="userDao" ref="userDao"></property>
    </bean>

在<property>标签里面,name属性指向的是ServiceImpl类里面的构造方法里面setUserDao里面的UserDao,其中set方法后面跟的属性名第一个字母必须大写,不然spring配置文件中识别不出这是对属性的set方法,可以理解为配置文件中是根据name的值去找符合规则且能对应上的set方法。而在配置文件中name=userDao的u可以小写也可以大写。而ref属性的userDao代表的是spring容器中已经有了的userDao对象,所以这里的值应该跟userDao的bean标签里面的Id属性一致。

注:为了使 JavaBean 的属性名和存取方法都符合规范, Sun 在 JSR 文档中规定了属性名和存取方法名的映射规则: ① 属性名对应的存取方法为 ge t/set 加上首字母大写的属性名,如属性 userName 的存取方法为 setUserName/getUserName 。这样属性名和存取方法都符合命名规范。这个规则强制的,如果不符合规则就会出现异常,在xml配置文件中

 这里p:后面跟着userDao-ref,ref="userDao",意思是注入的不是一个基础变量,是一个引用变量,引用的指向是userDao的id值

(2)通过构造方法注入(有参构造)。

先在ServiceImpl设置一个有参的构造方法

    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }

    public UserServiceImpl() {
    }

然后在配置文件中编写bean标签

    <bean id="userService2" class="com.itheima.service.impl.UserServiceImpl">
        <constructor-arg name="userDao" ref="userDao"></constructor-arg>
    </bean>

其中<constructor-arg>指的是构造方法,name属性后面跟着的指的是ServiceImpl有参构造方法中的属性名,而ref指向的是spring容器中的对象,即userDao的bean标签的id属性值。

5、普通数据类型、集合的依赖注入

假设,在userDaoImpl实现类中创建了以下的属性:

    private String username;
    private int age;    
    private List<String> strList;
    private Map<String, User> userMap;
    private Properties properties;

可以在bean标签内为这些属性注入值:

    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
        <property name="username" value="zhangsan"/>
        <property name="age" value="18"/>
        <property name="strList">
            <list>
                <value>aaa</value>
                <value>bbb</value>
                <value>ccc</value>
            </list>
        </property>
        <property name="userMap">
            <map>
                <entry key="u1" value-ref="user1"></entry>
                <entry key="u2" value-ref="user2"></entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="p1">ppp1</prop>
                <prop key="p2">ppp2</prop>
                <prop key="p3">ppp3</prop>
            </props>
        </property>
    </bean>

可以看到,对于普通数据类型、集合的注入,采用的是类似于对象set方法注入的<property>标签,里面没有ref属性,因为ref属性是针对对象的,而是根据具体属性的类型采用不同的标签。

2、原始注解

需要在配置文件中配置注解搜寻器,告诉spring去哪里找注解

<context:component-scan base-package="com.gdut"></context:component-scan>

 1、@Repository

//<bean id="userDao" class="com.gdut.depen.Dao.Impl.DaoImpl">
@Repository("userDao")

采用@Repository注解可以带起在配置文件中的<bean>,因为这个注解是在类的上面,所以就可以直接找到这个类而不需要<bean>里面的class值;注解里面的值等价于<bean>里面的id属性。

2、@Service("userService")

道理等同@Repository。

3、注入对象属性

对于注解注入对象,需要用到以下注解来完成把spring中已经有的对象注入给目标属性

例如在serviceImpl中需要userDao对象,serviceImpl类中创建了一个userDao变量

private userDao userDao;

3、@Autowired+@Qualifier=@Resource

    @Autowired
    @Qualifier("userDao")
    private useDao userDao;

这样就相当于把spring容器中id为userDao的对象赋给该类的属性userDao,相当于<property name="userDao" ref="userDao"></property>

当使用这些注解的时候,set方法可以不写。把注解放在属性上,就直接通过反射赋值给了属性。

3.1@Resource

如果使用@Ressource,就等同于同时使用@Autowired+@Qualifier的效果

    @Resource(name = "userDao")
    private Dao userDao;

name属性指向的是bean的id属性

3.2@Autowired

可以单独使用@Autowired。

@Autowired
private Dao userDao;

这个注解直接按照数据类型useDao在spring容器中进行匹配,在spring中找userDao的bean,如果找到了直接注入到该属性中,但是如果spring中有多个userDao的bean,就不知道注入哪个了。

3.3@Qualifier

这个注解需要搭配@Autowired一起使用

    @Autowired
    @Qualifier("userDao")
    private useDao userDao;

这时候@Qualifier里面的字符串是值bean标签的id属性,即此时是根据id值跟容器中的值进行匹配,如果spring容器里面有多个同类对象,可以通过唯一标识id注入。

4、注入普通属性

@Value("gdut")
private string school;

这个注解考虑如下使用场景:

配置文件中载入了一个properties文件,里面放着关于数据源的相关信息:

<!--加载外部的properties文件-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root

如果是在配置文件中载入这些数据是通过以下的bean标签:

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

通过${key},就可以获得properties文件中对应的value

在Java类中使用该bean:

ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = app.getBean(DataSource.class);
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();

而如果使用value注解,则可以直接获得对应的value值:

    @Value("${jdbc.driver}")
    private String driver;

5、新注解

 5.1@Configuration、@ComponentScan、@Import

//标志该类是Spring的核心配置类
@Configuration
//<context:component-scan base-package="com.itheima"/>
@ComponentScan("com.itheima")
//<import resource=""/>
@Import({DataSourceConfiguration.class})
public class SpringCofiguration {

}

 思想的转换:使用一个Java类去代替applicationContext.xml

5.2@PropertySource、@Bean

//<context:property-placeholder location="classpath:jdbc.properties"/>
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfiguration {

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

    @Bean("dataSource")  //Spring会将当前方法的返回值以指定名称存储到Spring容器中
    public DataSource getDataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(username);
        dataSource.setPassword(password);
        return dataSource;
    }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring依赖注入 的相关文章

随机推荐