Spring框架 (9) —— 模拟注册功能(使用注解方式)、纯注解配置

模拟注册功能(使用注解方式)

DAO层代码

//@Component("userDao")
@Repository("userDao")
public class UserDaoImpl implements UserDao {
	@Override
	public void insert(User user) {
		System.out.println("注册的Dao方法执行");
	}
}

Service层代码

@Service("userService")
public class UserServiceImpl implements UserService {
	
	/*@Autowired
	@Qualifier("userDao")*/
	
	@Resource(name="userDao")
	private UserDao dao;
	
	@Override
	public void register(User user) {
		dao.insert(user);
	}
	//因为要用
	public void setDao(UserDao dao) {
		this.dao = dao;
	}
}

表现层代码

@Controller
public class UserController {
	/*@Autowired
	@Qualifier("userService")*/
	@Resource(name="userService")
	private UserService service;
	
	public void register(User user) {
		
		service.register(user);
	}
}

测试代码

public class UserServletTest {
	
	@Test
	public void testSpring() throws Exception {		//创建用户对象:模拟接受用户参数,封装对象的过程
		User user = new User();
		user.setUsername("张三");
		user.setPassword("admin");
        UserController controller = context.getBean("userController",CustomerController.class);
		//执行注册操作
		controller.register(user);
	}
}

applicationContext.xml

配置文件(只需要配置一个包扫描即可)

	<!-- 配置包扫描
	cn.xc.spring : 此包以及子包全部被扫描
	 -->
<context:component-scan base-package="cn.xc.spring"/>

纯注解配置

问题

我们发现,之所以我们现在离不开xml配置文件,是因为我们有一句很关键的配置:

<!-- 告知spring框架在,读取配置文件,创建容器时,扫描注解,依据注解创建对象,并存入容器中 -->
	<context:component-scan base-package="cn.zj.spring"></context:component-scan>

如果他要也能用注解配置,那么我们就可以脱离xml文件了。

通过@Configuration注解和@ComponentScan注解

替换XML配置文件的 @Configuration注解@Configuration配置类注解,在纯注解配置中,类加了该注解,就意味着该类是Spring的配置类。
该类的功能就是用于替代原来的XML配置文件。

作用:
用于指定当前类是一个spring配置类,当创建容器时会从该类上加载注解。
获取容器时需要使用AnnotationConfigApplicationContext
(有@Configuration注解的类.class)。
@ComponentScan注解@ComponentScan注解扫描类,作用就是配置扫描Spring组件类的路径。功能等同原来配置文件的
作用:
用于指定spring在初始化容器时要扫描的包。
作用和在spring的xml配置文件中的:
<context:component-scan base-package=“cn.zj.spring”/>是一样的。
属性:
basePackages:用于指定要扫描的包。
和该注解中的value属性作用一样。
@PropertySource注解作用:
用于加载.properties文件中的配置。
例如我们配置数据源时,可以把连接数据库的信息写到properties配置文件中,就可以使用此注解指定properties配置文件的位置。
属性:
value[]:用于指定properties文件位置。
如果是在类路径下,需要写上classpath:
@Bean注解作用:
该注解只能写在方法上,使用此方法创建一个对象,并且放入spring容器。
它就相当于我们之前在xml配置中介绍的<bean标签>
属性:
name:给当前@Bean注解方法创建的对象指定一个名称(即bean的id)。
@Import注解作用:
用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration注解。当然,写上也没问题。 <import >
属性:
value[]:用于指定其他配置类的字节码。
@Value注解读取properties配置文件以后, 使用 ${key}获取配置文件中对应的值 @Vlaue(“${jdbc.dirverClassName}”) private String driverClassName;

示例代码

简单入门

说明

需求:通过一个简单的入门示例,实现创建一个配置类使用**@Configuration注解和@ComponentScan**注解替换xml文件。

配置步骤

第一步:创建一个Java项目

创建一个Java项目,导入必须的jar包以及编写好需要的类结构。代码目录如下:
在这里插入图片描述

第二部:编写dao层、pojo层、service层、controller层代码

dao层

package cn.xc.spring.dao;
import cn.xc.spring.pojo.User;
public interface UserDao {
	public void insert(User user);
}
package cn.xc.spring.dao.impl;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import cn.xc.spring.dao.UserDao;
import cn.xc.spring.pojo.User;

@Repository
public class UserDaoImpl implements UserDao {

	@Autowired
	private DataSource datasource;

	@Override
	public void insert(User user) {
		try {
			Connection conn = datasource.getConnection();
			System.out.println("conn:" + conn);
			System.out.println("UserDaoImpl.insert()");
			System.out.println("user" + user);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

pojo层

package cn.xc.spring.pojo;

public class User {
	private Integer id;
	private String name;
	private String password;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public User(Integer id, String name, String password) {
		super();
		this.id = id;
		this.name = name;
		this.password = password;
	}

	public User() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", password=" + password + "]";
	}

}

service层

package cn.xc.spring.service;
import cn.xc.spring.pojo.User;
public interface UserService {
	public void insert(User user);
}
package cn.xc.spring.service.impl;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import cn.xc.spring.dao.UserDao;
import cn.xc.spring.pojo.User;
import cn.xc.spring.service.UserService;
@Service
public class UserServiceImpl implements UserService {
	/*
	 * @Autowired Spring指定标签
	 * 
	 * @Resource JavaEE官方指定标签
	 */
	// @Autowired
	@Resource
	private UserDao userDao;
	@Override
	public void insert(User user) {
		userDao.insert(user);
	}
}

controller层

package cn.xc.spring.controller;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;

import cn.xc.spring.pojo.User;
import cn.xc.spring.service.UserService;

@Controller
public class UserController {

	@Resource
	private UserService userService;

	public void save(User user) {
		userService.insert(user);
	}
}

第三步:编写配置类代码

通过该配置类的代码替换掉Spring配置文件

package cn.xc.spring.config;

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 com.alibaba.druid.pool.DruidDataSource;

/*
 * @Configuration 
 * 说明把当前类当做成Spring框架的配置文件
 * @ComponentScan 
 *  配置注解包扫描的位置
 * @PropertySource("classpath:db.properties")
 *  读取.peroperties 后缀的配置文件
 */

@Configuration
//@ComponentScan(basePackages= {"cn.xc.spring.action","cn.xc.spring.service","cn.xc.spring.dao"})
@ComponentScan("cn.xc.spring")
@PropertySource("classpath:db.properties")
public class SpringConfig {
	
	/**
	 * @Value(value="")
	 * 可以从Spring容器读取 .properties 配置文件内容
	 * value :配置文件的对应的key -->使用 ${key} 获取
	 * 程序运行中自动将 properties 对应key的获取出来设置给字段
	 * 
	 */
	
	//等价 <property name="driverClassName" value="${jdbc.driverClassName}">
	@Value("${jdbc.driverClassName}") 
	private String driverClassName;
	
	@Value("${jdbc.url}")
	private String url;
	
	@Value("${jdbc.username}")
	private String username;
	
	@Value("${jdbc.password}")
	private String password;
	
	@Value("${jdbc.maxActive}")
	private Integer maxActive;
	
	//<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" 
  	//init-method="init" destroy-method="close">
	@Bean(name="dataSource",initMethod="init",destroyMethod="close")
	public DataSource getDataSource() {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName(driverClassName);
		dataSource.setUrl(url);
		dataSource.setUsername(username);
		dataSource.setPassword(password);
		dataSource.setMaxActive(maxActive);
		return dataSource;
	}
}

第四步:编写测试代码

package cn.xc.spring.test;

import java.sql.Connection;

import javax.sql.DataSource;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import cn.xc.spring.config.SpringConfig;

public class SpringTest {

	@Test
	public void testName() throws Exception {

		// 1.读取 xml 配置文件,启动框架,创建Spring容器对象
		//ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		// 1. 读取SpringConfig 类配置文件,启动动框架,创建Spring容器对象
		ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
		
		//2. 获取 连接池对象
		DataSource dataSource = context.getBean("dataSource", DataSource.class);
		
		//2.1获取数据库连接对象
		Connection conn = dataSource.getConnection();
		
		System.out.println(conn);
	}
}

测试结果,输出组件类调用方法的输出值。配置成功
在这里插入图片描述


版权声明:本文为weixin_41321790原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。