目录
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;
}