本文主要是介绍Spring4入门之第二章IOC的注解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Spring4入门之第二章IOC的注解
Spring整合数据库连接池
传统硬编码方式使用连接池
-
硬编码:
可以看出无论是哪个连接池都比较繁琐,复用性和可扩展性都很差
我们可以将其进一步的升级和Spring进行简单的整合
//C3p0的硬编码方式: public void demo1() throws PropertyVetoException, SQLException {ComboPooledDataSource c3p0DataSource = new ComboPooledDataSource();c3p0DataSource.setDriverClass("com.mysql.jdbc.Driver");c3p0DataSource.setJdbcUrl("jdbc:mysql:///sh_day04");c3p0DataSource.setUser("root");c3p0DataSource.setPassword("root");Connection conn = c3p0DataSource.getConnection();System.out.println(conn);} //DBCP的硬编码方式: public void demo2() throws SQLException {BasicDataSource dbcpDataSource = new BasicDataSource();dbcpDataSource.setDriverClassName("com.mysql.jdbc.Driver");dbcpDataSource.setUrl("jdbc:mysql:///sh_day04");dbcpDataSource.setUsername("root");dbcpDataSource.setPassword("root");Connection conn = dbcpDataSource.getConnection();System.out.println(conn);}
-
Spring和数据库连接池进行简单的整合
上面的硬编码方式我们可以将对象的创建权和属性的注入全部交给Spring进行管理(IOC和DI)
比如:ComboPooledDataSource c3p0DataSource = new ComboPooledDataSource();(外部类对象的创建)
c3p0DataSource.setDriverClass(“com.mysql.jdbc.Driver”);(属性的注入)
我们可以在Spring容器的配置文件中
配置:如下代码
applicationContext.xml
<!-- Spring整合C3P0数据库连接池的普通方式 --><bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.jdbc.Driver" /><property name="jdbcUrl" value="jdbc:mysql:///sh_day04" /><property name="user" value="root" /><property name="password" value="root" /></bean><!-- Spring整合DBCP数据库连接池的普通方式 --><bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///sh_day04"/><property name="username" value="root"/><property name="password" value="root"/></bean>
编写测试代码:
public void demo3() throws SQLException {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");//C3P0DataSource c3p0DataSource = (ComboPooledDataSource) applicationContext.getBean("c3p0");//DBCPDataSource dbcpDataSource = (BasicDataSource) applicationContext.getBean("dbcp");Connection connC3P0 = c3p0DataSource.getConnection();Connection connDBCP = dbcpDataSource.getConnection();System.out.println(connC3P0);System.out.println(connDBCP);}
整合使用数据库连接池
-
对于上面的两种方式,无论哪一种,代码的可扩展性都非常差
-
于是我们可以使用将数据库的连接等信息以配置文件的方式让Spring区进行加载
-
步骤思想:
- 将数据库的连接Driver、url、user和password等等,以配置文件jdbc.properties的方式脱离applicationContext.xml文件
- Spring通过什么标签或者功能去读取jdbc.properties
- 如何通过jdbc.properties文件动态获取里面的数据,并使Spring动态的和获取
-
问题解答:
-
jdbc.properties文件:
#mysqljdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql:///sh_day04 jdbc.username=root jdbc.password=root#Oracle#jdbc.driver=oracle.jdbc.OracleDriver #jdbc.url=jdbc:oracle:thin:@192.168.0.X:1521:xe #jdbc.username=root #jdbc.password=root#DB2#jdbc.driver=com.ibm.db2.jcc.DB2Driver #jdbc.url=jdbc:db2://localhost:50000/toolsdb #jdbc.username=root #jdbc.password=root
-
Spring通过标签:可以读取到classpath(src下)的jdbc.properties文件
<context:property-placeholder location="classpath:jdbc.properties" />
-
然后通过${}表达式获取Spring已经读取到的jdbc.properties文件中的属性值
<!-- Spring整合数据库连接池的最终方式 --><context:property-placeholder location="classpath:jdbc.properties" /><bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${jdbc.driver}" /><property name="jdbcUrl" value="${jdbc.url}" /><property name="user" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /></bean><bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource"><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean>
-
Spring整合Junit测试
-
普通测试的缺点:
代码复用性太大
配置文件运行一次加载一次
-
Spring整合Junit开发的步骤:
-
导包:
spring-test.jar :增强
spring-aop.jar :可以写注解
junit.jar :之前的测试 -
要告诉spring谁加载配置文件 (SpringJunt4ClassRunner.class)
-
通知spring配置文件的地址
-
分层测试
-
-
在Spring中spring-test.jar包中对Junit进行了加强,Spring通过SpringJunt4ClassRunner加载配置文件,同时对于Junit本身测试的一部分不改动
-
两个注解
- @ContextConfiguration(“classpath:applicationContext.xml”)(告诉Spring配置文件的位置)
- @RunWith(value = SpringJUnit4ClassRunner.class)(告诉Spring谁去加载配置文件)
-
导包 在Spring3之后需要导入spring-aop.jar
-
开启注解扫描器 告诉spring应该去那个包下面解析注解,使用IOC的注解开发,配置扫描(哪些包下的类使用IOC注解)!!!扫描是为了扫描类上的注解。
<context:component-scan base-package="com.syj.spring" />
-
配置注解组件 Component
-
测试(使用上面的数据库连接池)
//告诉Spring配置文件的位置 @ContextConfiguration("classpath:applicationContext.xml") //告诉Spring谁去加载配置文件 @RunWith(value = SpringJUnit4ClassRunner.class) public class SpringJunit {@Resource(name = "c3p0")private DataSource c3p0DataSource;@Resource(name = "dbcp")private DataSource dbcpDataSource;@Testpublic void demo1() throws SQLException {// Connection connection = c3p0DataSource.getConnection();Connection connection = dbcpDataSource.getConnection();System.out.println(conection);} }
注解的开发
类上的注解<bean id="" class="" />
-
@Component(“bean的id值”) 定义在类上 只要定义在了类上
-
那么注解扫描器只要一扫描到就会创建该类的实例对象 放在spring容器中
-
spring发布了公告, @Component这个注解不维护了,要维护这个注解下面衍生出的3个注解
注解 描述 @Controller(“bean的id值”) 针对的就是web层 @Service(“bean的id值”) 针对的是service层 @Repository(“bean的id值”) 针对的是dao层
属性值的注解
-
@Value(“属性值”),定义在属性字段上,针对的是基本类型和String类型
如果使用了这个注解 该属性的set方法可以省略不写(如果写了set方法注解写在set方法上面,没有set方法直接写在属性上)
-
@Autowired,类型。 定义在属性字段上的 ,针对的是对象类型,
如果定义在了那个对象类型的属性身上,会自动去spring容器中找该类型的实例对象给赋值
-
@Qualifier(“userDaoxxx”),名称。定义在属性字段上的,指定用该类型的哪个id名称的实例对象
-
@Resource(name=“userDaoxxx”)
@Autowired+@Qualifier(“userDaoxxx”) -
@Autowired针对的类型Autowired和Qualifier决定属性的名称应该保持一致。这两个的用法和Resource的用法效果一样,应该和属性id一致。
-
但是真正在使用开发中@Autowired比@Resource使用的多
需要了解的注解
-
@Scope("singleton"或则prototype):定义在类上的 指定当前类是单实例还是多实例
-
@PostConstruct:定义在方法上 配置初始化方法
-
@PreDestroy:定义在方法上 配置销毁的方法
Spring的新注解(完全代替XML方式)
-
完全用注解的方式 完全抛弃掉xml配置文件
-
半注解半xml方式:
别人的类用xml
自己的类用注解 -
全注解方式:
别人类要用注解
自己的类也要用注解 -
条件: 需要有一个注解类,不在加载配置文件 而是加载这个注解类
Service调Dao全注解方式(自己的类)
-
使用到的注解
- @Repository(“userDao”)—>创建一个UserDaoImpl的实现类(Spring new UserDaoImpl())
- @Service(“userService”)—>创建一个userServiceImpl的实现类(Spring new UserServiceImpl())
- @Value(“猪八戒”)—>在UserDao的实现类UserDaoImpl中给name属性注入“猪八戒”值
- @Resource(“userDao”)—>在userServiceImpl的类中给UserDao属性进行(对象)赋值
-
使用全注解的步骤:
-
创建一个注解类(代表这个注解类就类比于applicationContext.xml文件)在applicationContext.xml文件可以编写的基本都可以找到对应的注解代替
-
在applicationContext.xml中的配置扫描包,的注解代替@ComponentScan
@ComponentScan(basePackages = “com.syj.spring”) 相当于:
<context:component-scan base-package="com.syj.spring" />
-
-
编写注解类
@Configuration // 表示该类是一个注解类 @ComponentScan(basePackages = "com.syj.spring") // 代替<context:component-scan base-package="com.syj.spring" /> public class SpringAnnotationClass {}
-
编写测试
@Testpublic void dmeo1() {//加载注解类ApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(SpringAnnotationClass.class);UserService userService = (UserService) annotationConfigApplicationContext.getBean("userService");userService.save();}
-
流程详解:
- 当在测试代码中加载pplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(
SpringAnnotationClass.class);的时候,Spring会去加载该类(发现时是注解类) - 执行到注解@ComponentScan(basePackages = “com.syj.spring”) 的时候开始扫描com.syj.spring包下的所有子包的类在并执行相应的注解,
- 因为在UserDaoImpl和UserServiceImpl有注解存在,所以创建了对象的实例和注入了相应的属性
- 取出指定的属性并执行相应的程序代码
- 当在测试代码中加载pplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(
C3P0数据库连接池全注解方式(外部引入的类)
-
目的将Spring和数据库连接池整合的修改为全注解方式
-
需要改为注解的在applicationContext.xml中的位置
-
加载jdbc.properties配置文件的标签
<context:property-placeholder location="classpath:jdbc.properties" />
-
交给Spring创建的C3P0核心实现类ComboPooledDataSource
<bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource"> </bean>
-
从jdbc.properties配置文件中动态获取连接数据库的属性
<property name="driverClass" value="${jdbc.driver}" /><property name="jdbcUrl" value="${jdbc.url}" /><property name="user" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" />
-
${}的加载
-
-
注解代替:
-
使用@propertySource(value=“classpath:jdbc.properties”)相当于在applicationContext.xml文件中配置
<context:property-placeholder location="classpath:jdbc.properties" />
-
在注解类中创建一个使用C3P0返回数据源的方法,并交给Spring进行管理
// 配置别人的类,将其加载进来// 这也是为什么不愿意使用全注解的(有的地方复杂) @Bean(name = "c3p0") // 相当于:<bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource"/> 起名相当于自己管理public DataSource getDataSource() throws PropertyVetoException {ComboPooledDataSource ds = new ComboPooledDataSource();ds.setDriverClass(driver);ds.setJdbcUrl(url);ds.setUser(username);ds.setPassword(password);return ds;}
-
在注解类中创建数据库连接池的属性使用注解@value进行属性注入
@Value("${jdbc.driver}")private String driver;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;
-
在4.3以前要给Spring配置一个解析器来解析${}
@Bean // 不加任何()内容代表交给Spring管理public static PropertySourcesPlaceholderConfigurer creatPropertySourcesPlaceholderConfigurer() {return new PropertySourcesPlaceholderConfigurer();}
-
此时已经将Spring整合数据库连接池从配置文件中脱离出来(亲测有效)
-
注解类的完整代码:
package com.syj.spring.demo6;import java.beans.PropertyVetoException;import javax.sql.DataSource;import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;import com.mchange.v2.c3p0.ComboPooledDataSource;@Configuration // 表示该类是一个注解类 @ComponentScan(basePackages = "com.syj.spring") // 代替<context:component-scan base-package="com.syj.spring" /> @PropertySource(value = "classpath:jdbc.properties") // <context:property-placeholder// location="classpath:jdbc.properties" /> public class SpringAnnotationClass {@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(name = "c3p0") // 相当于:<bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource"// />起名相当于自己管理public DataSource getDataSource() throws PropertyVetoException {ComboPooledDataSource ds = new ComboPooledDataSource();ds.setDriverClass(driver);ds.setJdbcUrl(url);ds.setUser(username);ds.setPassword(password);return ds;}// 4.3以前要给Spring配置一个解析器来解析${}@Bean // 不加任何()内容代表交给Spring管理public static PropertySourcesPlaceholderConfigurer creatPropertySourcesPlaceholderConfigurer() {return new PropertySourcesPlaceholderConfigurer();} }
-
测试代码
@Testpublic void dmeo2() throws SQLException {ApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(SpringAnnotationClass.class);DataSource ds = (DataSource) annotationConfigApplicationContext.getBean("c3p0");System.out.println(ds.getConnection());}
-
-
流程详解
- 在执行到ApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(
SpringAnnotationClass.class);时。Spring会主动寻找该类,并加载 - 因为注解类上别的注解的存在,所以会加载依次加载@ComponentScan(basePackages = “com.syj.spring”) ,创建一系列的实例对象。
- 同时通过@PropertySource(value = “classpath:jdbc.properties”) 告诉Spring要加载的配置文件jdbc.properties
- 之后便通过属性注入为数据库连接池中的driver,url,username和password赋值(加载${}解析器)
- 同时将别人的类C3P0加载进Spring容器,并命名为c3p0
- 获取数据源对象
- 租后进行一系列的数据库的交互
- 在执行到ApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(
这篇关于Spring4入门之第二章IOC的注解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!