一、IOC注解
A 使用注解需要在XML中开启包扫描
context:component-scan标签 (包扫描)
base-package属性:包名
* spring容器创建的时候,自动扫描配置了spring注解的包
B property文件的加载
1.通过 name value属性,完成property文件内容的注入
2.通过name,array标签结合子标签value完成property文件内容的注入
spring中借助PropertySourcesPlaceholderConfigurer加载配置文件:
C 创建对象交给spring容器管理,作用在类上
- @Component : 默认创建的对象的唯一标识,当前类名,首字母小写
- @Controller : web层
- @Service : service层
- @Repository : dao层
value属性 : 指定的bean象的唯一标识
二、DI注解
@Autowired : 自定装箱(使用暴力反射直接对依赖关系对象字段赋值)
. 作用范围:
a成员变量写在字段上可以不写set和构造方法
b set方法上
c构造方法上
1.安装当前接口的类型,从spring从其中查找对象
2.安装属性名作为唯一标识从容器中查找对象,配合@Qualifier@Qualifier : 结合@Autowired配合使用
value属性:bean对象的唯一标识
1.按照类型从从其中查找
2.按照指定唯一标识从容器中获取
作用范围:
a成员变量写在字段上可以不写set和构造方法
b set方法上:将指定id的对象,set方式注入
c构造方法上:将指定id的对象,构造方式注入
c行参上:将指定id的对象,作为行参数注入@Resourc : 依赖注入(不写属性,默认按类型注入)
name属性:bean对象的唯一标识
jdk提供的依赖注入的注解@Value:
1.注入基本数据类型
2.注入被spring管理的properties文件中的内容(通过el表达式取值)
<!-- 开启对ioc注解的支持
1.需要使用context的名称空间
2.context:component-scan (包扫描)
base-package:包名
* spring容器创建的时候,自动扫描配置了spring注解的包
-->
<context:component-scan base-package="cn.it"></context:component-scan>
<!-- properties需要交给spring容器管理
PropertySourcesPlaceholderConfigurer : 加载properties配置文件
读取文件中的内容,将文件中内容已 key = value 的形式存储到java内存中
PropertySourcesPlaceholderConfigurer config = new PropertySourcesPlaceholderConfigurer();
config.setLocation("类路径下,jdbc.properties");
-->
<bean id="propertySource" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<!-- 1.通过 name value属性,完成property文件内容的注入
2.通过name,array标签结合子标签value完成property文件内容的注入 -->
<!-- <property name="location" value="classpath:jdbc.properties"></property> -->
<property name="locations">
<array>
<value>classpath:jdbc.properties</value>
</array>
</property>
</bean>
/**
* 1.@Repository("userDao") IOC:交给spring管理
*
* 2.@Scope("singleton")
* value属性设置作用域
* 1)singleton:单例(默认值)
2)prototype:多例
* 3.@PostConstruct:初始化对象后立刻执行的方法
* 4.@PreDestroy:销毁对象前执行的方法
*
* 5.@Autowired:自动装载交给spring容器管理 DI
* 6.@Qualifier("run"):value属性设置被管理对象的id
* 7.@Value:
1).注入基本数据类型
2).注入被spring管理的properties文件中的内容(通过el表达式取值)
*
*/
@Repository("userDao")
@Scope("singleton")
public class UserDaoImpl implements UserDao {
@Value("${jdbc.username}")
private String user;
@Value("${jdbc.password}")
private String password;
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String Url;
@Autowired
@Qualifier("run")
private QueryRunner run;
@PostConstruct
@Bean("run")
public QueryRunner getQueryRunner() {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
try {
dataSource.setDriverClass(driver);
} catch (PropertyVetoException e) {
e.printStackTrace();
}
dataSource.setJdbcUrl(Url);
System.out.println(dataSource.getDriverClass());
return new QueryRunner(dataSource);
}
@PreDestroy
public void destory() {
System.out.println("dao销毁了");
}
/** 查询所有 */
public List<User> FindAll() throws SQLException {
return run.query("select * from user ", new BeanListHandler<>(User.class));
}
}
三.作用域(对象的生命周期)注解
@Scope:创建对象的作用域,写在实现类上
singleton:单例(默认值)
prototype:多例
注意:当多实例对象存在需要被其他对象注入时,会报错@PostConstruct : 初始化方法(写子实现类的方法上)
创建对象之后,立即执行的方法@PreDestroy:销毁方法(写子实现类的方法上)
对象销毁之前,执行的方法
和spring容器的生命周期有管
当单例对象:容器关闭,(销毁方法),销毁对象
当多例对象:容器管理
四、.纯注解编程
问题:创建spring容器的时候,是否需要配置信息
1.配置文件中(bean.xml) (X)
2.java对象
* spring的配置类
* spring的配置信息
1.声明配置类
@Configuration : 声明配置类
2.开启包扫描(开启对IOC注解的支持)
@ComponentScan
basePackages : 扫描的包名(扫描此包以及此包下的所有子包)
3.加载properties配置文件的
@PropertySource :
value : 接收一个string类型的数组
配置文件的路径,类路径下classpath:
纯注解获取spring容器
/**
* AnnotationConfigApplicationContext
* 通过配置类创建spring容器
* class : 配置类的字节吗
*/
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
4).@Import:引入其他类配置文件
* value = XXX.class value 属性为要引入包的字节码文件
@Bean
1.需要配置到方法
2.此方法的返回值交给spring容器管理
name:bean的唯一标识
@Qualifier : 配置到方法参数上
表名此方法参数的注入过程中,是按照指定的bean的唯一标识从容器中查找
/**
* 1.@Configuration:声明该类为配置类
* 2.@ComponentScan:开启包扫描
* basePackages="cn.cting":开启包扫描,属性为要扫描包的字节码
* 3.@Import:引入其他类配置文件
* value = XXX.class value 属性为要引入包的字节码文件
* 4.@PropertySource:读取property配置信息交给spring容器管理
* value属性为:文件名的类路径字符串 classpath:开头代表类路径,
*
*/
@Configuration
@ComponentScan(basePackages = "cn.it")
//引入其他配置文件
@Import(jdbcConfig.class)
public class SpringConfig {
}
/**
* 1.@Configuration:声明该类为配置类
* 2.@PropertySource:读取property配置信息交给spring容器管理
* value属性为:文件名的类路径字符串 classpath:开头代表类路径,后面跟路径
* 3.@Value("${jdbc.username}"):为成员变量赋值(基本类型值),用springEl表达式从spring容器中取值
* 4.@Bean 调用该方法,将该方法的返回值交给spring容器管理
* value属性,指定该对象在spring容器中的id为value的值
* 5.@Qualifier:value属性指定从spring注入时,由通过类型查找,改为通过id查找,id为value属性的值
*/
@Configuration
@PropertySource("classpath:jdbc.properties")
public class jdbcConfig {
@Value("${jdbc.username}")
private String User;
@Value("${jdbc.password}")
private String password;
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String Url;
@Bean("queryRunner")
public QueryRunner getQueryRunner(@Qualifier("dataSource")DataSource ds) {
System.out.println("调用了创建queryRunner的方法");
return new QueryRunner(ds);
}
@Bean("dataSource")
public DataSource getDataSource() {
System.out.println("调用了创建datasourse的方法");
ComboPooledDataSource ds = new ComboPooledDataSource();
ds.setUser(User);
System.out.println("====================");
ds.setPassword(password);
try {
ds.setDriverClass(driver);
} catch (PropertyVetoException e) {
e.printStackTrace();
}
ds.setJdbcUrl(Url);
return ds;
}
}
五、.spring中的junit单元测试
i:指定spring提供的单元测试环境,写在测试类上
1. @RunWith(SpringJunit4ClassRunner.class)
ii: 指定spring容器的配置信息
2. @ContextConfiguration
locations : xml的配置文件(xml,注解结合xml)
classes :配置类的字节码(纯注解)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=SpringConfig.class)
//@ContextConfiguration(locations="classpath:bean.xml")
public class testUser {
@Autowired
private UserService userService;
@Autowired
private ApplicationContext ac;
@Test
public void testInsert() throws Exception {
List<User> findAll = userService.FindAll();
System.out.println(ac);
for (User user : findAll) {
System.out.println(user);
}
}
}