SSH框架之Spring第二篇

  • 2019 年 10 月 6 日
  • 筆記

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

本文链接:https://blog.csdn.net/zhao1299002788/article/details/101167807

1.1 基于注解的IOC配置  		既注解配置和xml配置要实现的功能都是一样的,都是要降低程序间的耦合.只是配置的形式不一样.    	1.2 环境搭建  		1.2.1 第一步:拷贝必备的jar包  		需要多拷贝一个spring-aop-4.2.4.RELEASE.jar  		1.2.2 创建xml文件,导入约束  			<?xml version="1.0" encoding="UTF-8"?>  			<!-- 导入schema  			约束的位置在:  				..spring-framework-4.2.4.RELEASEdocsspring-framework-referencehtmlxsd-configuration.html  				文件中。  			注意:要导入schema约束  			-->  			<beans xmlns="http://www.springframework.org/schema/beans"  				  xmlns:context="http://www.springframework.org/schema/context"  				   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  				   xsi:schemaLocation="http://www.springframework.org/schema/beans  							http://www.springframework.org/schema/beans/spring-beans.xsd  							http://www.springframework.org/schema/context  							http://www.springframework.org/schema/context/spring-context.xsd ">  			</beans>  		1.2.3 使用@Component注解配置管理的资源  			/**  			 * 客户的业务层实现类  			 * @author zhy  			 *  			@Component(value="customerService")  			public class CustomerServiceImpl implements ICustomerService {  				@Override  				public void saveCustomer() {  					System.out.println("执行了保存客户");  				}  			}  		1.2.4 第四步在spring的配置文件中开启spring对注解ioc的支持  			<!--告知spring框架在,读取配置文件,创建容器时,扫描注解,依据注解创建对象,并存入容器中.>  				<context:component-scan base-package="com.baidu"></context:component-sacn>  	1.3 常用注解  		1.3.1 用于创建对象的  			相当于 : <bean id="" class="">  		1.3.1.1 @Component  			作用:  				把资源让spring来管理.相当于在xml配置一个bean.  			属性:  				value: 指定bean的id.如果不指定value属性,默认bean的id是当前类的类名.首字母小写.  		1.31.2 @Controller @Service @Repository  			们三个注解都是针对一个的衍生注解,他们的作用及属性都是一模一样的。  			他们只不过是提供了更加明确的语义化。  				@Controller:一般用于表现层的注解。  				@Service:一般用于业务层的注解。  				@Repository:一般用于持久层的注解。  			细节:如果注解中有且只有一个属性要赋值时,且名称是value,value在赋值是可以不写。  		1.3.2 用于注入数据的  			相当于 : <property name="" ref="">  或者 <property name="" value="">  			1.3.2.1@Autowired  			作用:  				自动按照类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他bean类型。当有多个类型匹配时,使用要注入的对象变量名称作为bean的id,在spring容器查找,找到了也可以注入成功。找不到就报错。  				/**  				 * 	@Autowired	自动装配,自动按类型注入对象  				 * 	<bean id="userService" class="com.baidu.demo2.UserServiceImpl" scope="" init-method="init">  				 * 		<property name="userDao" ref="ud"/>  				 * 	</bean>  				 *  				 * 	@Autowired  					@Qualifier(value="userDao")	这2个注解必须要一起使用,按id名称注入    					@Resource	是Java提供注解,Spring容器支持该注解。可以通过name在容器中查找指定名称的对象  				 *  			1.3.2.2@Qualifier  			作用:  				在自动按照类型注入的基础之上,再按照Bean的id注入。它在给字段注入时不能独立使用,必须和@Autowire一起使用;但是给方法参数注入时,可以独立使用。  			属性:  				value:指定bean的id。  			1.3.2.3@Resource  			作用:  				直接按照Bean的id注入。它也只能注入其他bean类型。  			属性:  				name:指定bean的id。  			1.3.2.4@Value  			作用:  				注入基本数据类型和String类型数据的  			属性:  				value:用于指定值  			1.3.3用于改变作用范围的:  				相当于:<bean id="" class="" scope="">  			1.3.3.1@Scope  			作用:  				指定bean的作用范围。  			属性:  				value:指定范围的值。  					   取值:singleton  prototype request session globalsession  			1.3.4和生命周期相关的:(了解)  				相当于:<bean id="" class="" init-method="" destroy-method="" />  			1.3.4.1@PostConstruct  			作用:  				用于指定初始化方法。  			1.3.4.2@PreDestroy  			作用:  				用于指定销毁方法。  			1.3.5代码示例  			业务层代码:  			/**  			 * 客户的业务层接口  			 */  			public interface ICustomerService {  				/**  				 * 保存客户  				 * @param customer  				 */  				void saveCustomer();  			}      			/**  			 * 客户的业务层实现类  			 */  			//作用就相当于在xml中配置了一个bean标签,该注解有value属性,含义是bean的id。  			//不写的时候,默认的id是:当前类名,且首字母小写。即:customerServiceImpl  			@Component(value="customerService")  			@Scope(value="singleton")  			public class CustomerServiceImpl implements ICustomerService {  			//	@Autowired  			//	自动按照数据类型注入,拿着当前变量的数据类型在spring的容器中找,找到后,给变量赋值。  			//	当有多个类型匹配时,会使用当前变量名称customerDao作为bean的id,继续在容器中找。  			//	找到了,也能注入成功。找不到就报错。  			//	@Qualifier(value="customerDao2")//在自动按照类型注入的基础之上,再按照id注入  				@Resource(name="customerDao2")//直接按照bean的id注入  				private ICustomerDao customerDao = null;    				@Value("com.mysql.jdbc.Driver")//注入基本类型和String类型数据  				private String driver;    				@Override  				public void saveCustomer() {  					System.out.println(driver);  					customerDao.saveCustomer();  				}  			}      			持久层代码:  			/**  			 * 客户的持久层接口  			 */  			public interface ICustomerDao {  				/**  				 * 保存客户  				 */  				void saveCustomer();  			}        			/**  			 * 客户的持久层实现类11111111111111111111  			 */  			@Repository("customerDao1")  			public class CustomerDaoImpl implements ICustomerDao {    				@Override  				public void saveCustomer() {  					System.out.println("保存了客户111111111111111111");  				}  			}    			/**  			 * 客户的持久层实现类222222222222222222222222  			 */  			@Repository("customerDao2")  			public class CustomerDaoImpl2 implements ICustomerDao {    				@Override  				public void saveCustomer() {  					System.out.println("保存了客户2222222222222222222");  				}  			}    			测试类代码:  			public class Client {  				public static void main(String[] args) {  					//1.获取容器  					ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");  					//2.根据id获取对象  					ICustomerService cs = (ICustomerService) ac.getBean("customerService");				cs.saveCustomer();  				}  			}    			配置文件:  			<?xml version="1.0" encoding="UTF-8"?>  			<!-- 我们导入约束时,除了昨天的那部分之外,还要单独导入一个context名称空间 -->  			<beans xmlns="http://www.springframework.org/schema/beans"  				   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  				   xmlns:context="http://www.springframework.org/schema/context"  				   xsi:schemaLocation="http://www.springframework.org/schema/beans  						  http://www.springframework.org/schema/beans/spring-beans.xsd  						  http://www.springframework.org/schema/context  						  http://www.springframework.org/schema/context/spring-context.xsd">  				<!-- 告知spring框架在通过读取配置文件创建容器时,扫描的包,并根据包中类的注解创建对象-->  				<context:component-scan base-package="com.baidu"></context:component-scan>  			</beans>    		1.3.6 关于Spring注解和XML的选择问题  			注解的优势 :  				配置简单,维护方便(我们找到类,就相当于找到了对应的配置)  			XML的优势  :  				修改时,不用改源码.不涉及重写编译和部署.  			Spring管理Bean方式的比较 :  							基于XML配置						基于注解配置  				Bean定义	<bean id="..." class="..">		@Component	衍生类@Repository	@Service 	@Controller  				Bean名称	通过id或name指定				@Component("person")  				Bean注入	<property>或者通过p命名空间		@Autowired按类型注入	@Qualifier按名称注入  				生命过程,		init-method destroy-method	@PostConstruct初始化	@PreDestroy销毁	@Scope设置作用范围  				Bean作用范围	范围scope属性  				适合场景		Bean来自第三方,使用其它		Bean的实现类由用户自己开发  	1.5 spring的纯注解配置  		/**  			 * 客户的业务层实现类  			 */  			@Configuration//表明当前类是一个配置类  			@ComponentScan(basePackages = "com.baidu")//配置要扫描的包  			public class SpringConfiguration {  			}    			那么新的问题又来了,我们如何获取容器呢?  			public class Client {  				public static void main(String[] args) {  					//1.获取容器:由于我们已经没有了xml文件,所以再用读取xml方式就不能用了。  					//这时需要指定加载哪个类上的注解  					ApplicationContext ac =  						new AnnotationConfigApplicationContext(SpringConfiguration.class);  					//2.根据id获取对象  					ICustomerService cs = (ICustomerService) ac.getBean("customerService");  					cs.saveCustomer();  				}  			}  			1.5.3新注解说明  			1.5.3.1@Configuration  			作用:  				用于指定当前类是一个spring配置类,当创建容器时会从该类上加载注解。获取容器时需要使用AnnotationApplicationContext(有@Configuration注解的类.class)。  			属性:  				value:用于指定配置类的字节码  			示例代码:  			/**  			 * 用于初始化spring容器的配置类  			 */  			@Configuration  			public class SpringConfiguration{  			}  			1.5.3.2@ComponentScan  			作用:  				用于指定spring在初始化容器时要扫描的包。作用和在spring的xml配置文件中的:  			<context:component-scan base-package="com.baidu"/>是一样的。  			属性:  				basePackages:用于指定要扫描的包。和该注解中的value属性作用一样。    		1.5.3.4@Import  			作用:  				用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration注解。当然,写上也没问题。  			属性:  				value[]:用于指定其他配置类的字节码。  				示例代码:  			@Configuration  			@ComponentScan(basePackages = "cn.baidu.spring")  			@Import({ Configuration_B.class})  			public class Configuration_A {  			}    			@Configuration  			@PropertySource("classpath:info.properties")  			public class Configuration_B {  			}  		1.5.3.5@Bean  			作用:  				该注解只能写在方法上,表明使用此方法创建一个对象,并且放入spring容器。它就相当于我们之前在xml配置中介绍的factory-bean和factory-method。  			属性:  				name:给当前@Bean注解方法创建的对象指定一个名称(即bean的id)。  				示例代码:  			@Bean(name = "datasource2")  				public DataSource createDS() throws Exception {  					ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();  					comboPooledDataSource.setUser("root");  					comboPooledDataSource.setPassword("1234");  					comboPooledDataSource.setDriverClass("com.mysql.jdbc.Driver");  					comboPooledDataSource.setJdbcUrl("jdbc:mysql:///spring_ioc");  					return comboPooledDataSource;  				}  		单元整合  			/**  			 * Spring整合Junit单元测试  			 * @author Administrator  			 */  			@RunWith(value=SpringJUnit4ClassRunner.class)  			@ContextConfiguration(value="classpath:applicationContext.xml")  			public class Demo1 {    				// 测试哪个对象,可以使用resource注解把对象注入进来  				@Resource(name="userService")  				private UserService userService;    				@Resource(name="userDao")  				private UserDao userDao;    				/**  				 * Spring 整合Juint单元测试的方法  				 */  				@Test  				public void run3(){  					userService.save();  				}    				@Test  				public void run4(){  					// userService.update();  					userDao.save();  				}  		使用XML方式完成IOC的入门  			1. 导入jar包  			2. 编写接口和实现类  			3. 编写配置文件,管理实现类  			4. 编写入门的程序  		使用注解的方式完成IOC的入门  			1. 导入jar包  			2. 编写接口和实现类  			3. 编写applicationContext.xml配置文件,目的 : 让注解生效  			4. 在实现类上编写注解  			5. 编写入门的程序    		1. 管理类的  			@Component 		所有类都可以使用  			@Controller		Web层使用的注解,就是Action使用的.  			@Service 		业务层使用的注解  			@Repository		持久层使用的注解  		2. 依赖注入的注解 (set方法可以省略不写)  			@Value			给普通类型属性注入值(String int double)  			@Resource		给引用类型注入值的,强调 : 该注解的属性时name  			@Scope			对象作用范围,默认单例的.    		Spring整合WEB  			ServletContext对象,服务器启动就创建,服务器关闭就销毁.  			监听器 : 监听ServletContext域对象的创建和销毁的.  			ServletContextListener监听器 , init destory  			总结 :  				服务器启动后,Spring创建对象,Spring创建Web版本的工厂,把工厂保存到ServletContext域对象中.  			编写 :  				从ServletContext对象中获取到Web版本的工厂,从工厂中获取到Service对象,调用方法.