标签:NPU 说明 原因 tle update 介绍 邮件服务 定位 必须
????SSH:Spring . Struts1/2 . Hiberernate
????SSM:Spring . SpringMVC . Mybatis
????Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。
???????◆目的:解决企业应用开发的复杂性
???????◆功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
???????◆范围:任何Java应用
????Spring是一个轻量级**控制反转(IoC)和面向切面(AOP)**的容器框架。
???要谈Spring的历史,就要先谈J2EE。J2EE应用程序的广泛实现是在1999年和2000年开始的,它的出现带来了诸如事务管理之类的核心中间层概念的标准化,但是在实践中并没有获得绝对的成功,因为开发效率,开发难度和实际的性能都令人失望。
??曾经使用过EJB开发JAVA EE应用的人,一定知道,在EJB开始的学习和应用非常的艰苦,很多东西都不能一下子就很容易的理解。EJB要严格地实现各种不同类型的接口,类似的或者重复的代码大量存在。而配置也是复杂和单调,同样使用JNDI进行对象查找的代码也是单调而枯燥。虽然有一些开发工作随着xdoclet的出现,而有所缓解,但是学习EJB的高昂代价,和极低的开发效率,极高的资源消耗,都造成了EJB的使用困难。而Spring出现的初衷就是为了解决类似的这些问题。
???Spring的一个最大的目的就是使JAVA EE开发更加容易。同时,Spring之所以与Struts、Hibernate等单层框架不同,是因为Spring致力于提供一个以统一的、高效的方式构造整个应用,并且可以将单层框架以最佳的组合揉和在一起建立一个连贯的体系。可以说Spring是一个提供了更完善开发环境的一个框架,可以为POJO(Plain Ordinary Java Object)对象提供企业级的服务。
???Spring的形成,最初来自Rod Jahnson所著的一本很有影响力的书籍《Expert One-on-One J2EE Design and Development》,就是在这本书中第一次出现了Spring的一些核心思想,该书出版于2002年。另外一本书《Expert One-on-One J2EE Development without EJB》,更进一步阐述了在不使用EJB开发JAVA EE企业级应用的一些设计思想和具体的做法。有时间了可以详细的研读一下。
1、JAVA EE开发应该更加简单。
2、使用接口而不是使用类,是更好的编程习惯。Spring将使用接口的复杂度几乎降低到了零。
3、为JavaBean提供了一个更好的应用配置框架。
4、更多地强调面向对象的设计,而不是现行的技术如JAVA EE。
5、尽量减少不必要的异常捕捉。
6、使应用程序更加容易测试。
1、可以令人方便愉快的使用Spring。
2、应用程序代码并不依赖于Spring APIs。
3、Spring不和现有的解决方案竞争,而是致力于将它们融合在一起。
1、最完善的轻量级核心框架。
2、通用的事务管理抽象层。
3、JDBC抽象层。
4、集成了Toplink, Hibernate, JDO, and iBATIS SQL Maps。
5、AOP功能。
6、灵活的MVC Web应用框架。
推荐书籍:Spring in Action
package com.sxt.factory;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class ObjectFactory {
/**
* ioc 容器
* key 类的全路径
* value 类的对象
*/
public static Map<String,Object> ioc = new HashMap<String,Object>();
/**
* @Title: getInstance
* @author: Mr.T
* @date: 2019年11月20日 上午10:54:28
* @Description:
* 这种方案不足 ,利用反射的灵活可以创建各种对象,减少工厂的个数.但是 效率堪忧.
* 发现效率低的原因,由于IOC容器没有对象,所以需要使用反射进行创建对象,再放入IOC容器.
* 如果,需要使用时,IOC容器存在需要使用的对象,那么效率不仅仅没有降低,且提高了.
* 当项目启动时,就直接将需要创建的对象,放入IOC容器中
* @param <T>
* @param cls
* @return
* @return: T
*/
public static <T> T getInstance(Class<T> cls) {
/**
* 每次创建对象都是创建新的对象
*/
T t = null;
// 获取类的全路径
String key = cls.getName();
// 判断对象容器中是否存在 若存在直接取
if(ioc.containsKey(key)) {
return (T) ioc.get(key);
}
// 若不存在 则创建一个,返回 ,且将对象放入到IOC容器中
try {
t = cls.newInstance();
ioc.put(key, t);
} catch (Exception e) {
e.printStackTrace();
}
return t;
}
public void init() {
InputStream in = ObjectFactory.class.getClassLoader().getResourceAsStream("obj.properties");
Properties prop = new Properties();
try {
prop.load(in);
String dao = prop.getProperty("dao");
String service = prop.getProperty("service");
String[] classes = dao.split(",");
for (int i = 0; i < classes.length; i++) {
Class<?> cls = Class.forName(classes[i]);
String name = cls.getName();
Object obj = cls.newInstance();
ioc.put(name, obj);
}
classes = service.split(",");
for (int i = 0; i < classes.length; i++) {
Class<?> cls = Class.forName(classes[i]);
String name = cls.getName();
Object obj = cls.newInstance();
ioc.put(name, obj);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
dao=com.sxt.dao.impl.UserDaoImpl,com.sxt.dao.impl.ClassesDaoImpl
service=com.sxt.service.impl.UserServiceImpl,com.sxt.service.impl.ClassesServiceImpl
???在实际开发中,对象和方法是最基础,最核心的东西.Spring核心只进行对象和方法的管理.对象的管理,在Spring中被称之为IOC/DI-控制反转(Inversion of Control,缩写为IoC).
IOC控制反转:
???将对象的创建初始化的权利,从开发者手中转移到Spring容器.由Spring将程序中需要的对象进行创建和装配.减少了开发者对对象的管理工作.这种模式就被称之为控制反转.
**DI—Dependency Injection,即“依赖注入”**:
IoC的别名,2004年,Martin Fowler探讨了同一个问题,既然IoC是控制反转,那么到底是“哪些方面的控制被反转了呢?”,经过详细地分析和论证后,他得出了答案:“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理对象变为由IoC容器主动注入。于是,他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection,DI)”。他的这个答案,实际上给出了实现IoC的方法:注入。
所谓依赖注入,就是由IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。
所以,依赖注入(DI)和控制反转(IoC)是从不同的角度描述的同一件事情,就是指通过引入IoC容器,利用依赖关系注入的方式,实现对象之间的解耦
??spring下载地址:https://repo.spring.io/webapp/#/artifacts/browse/tree/General/release
??Spring Framework 5.2.x: JDK 8-14
??Spring Framework 5.1.x: JDK 8-12
??Spring Framework 5.0.x: JDK 8-10
??Spring Framework 4.3.x: JDK 6-8
??spring-aop:Spring的面向切面编程,提供AOP(面向切面编程)的实现
??spring-aspects:Spring提供的对AspectJ框架的整合
??spring-beans:Spring IOC的基础实现,包含访问配置文件、创建和管理bean等。
??spring-context:在基础IOC功能上提供扩展服务,此外还提供许多企业级服务的支持,有邮件服务、任务调度、JNDI定位,EJB集成、远程访问、缓存以及多种视图层框架的支持。
??spring-context-support:Spring context的扩展支持,用于MVC方面。
??spring-core:Spring的核心工具包
??spring-expression:Spring表达式语言
??spring-instrument:Spring对服务器的代理接口
??spring-instrument-tomcat:Spring对tomcat连接池的集成
??spring-jdbc:对JDBC 的简单封装
??spring-jms:为简化jms api的使用而做的简单封装
??spring-messaging:消息支持相关包
??spring-orm:整合第三方的orm实现,如hibernate,ibatis,jdo以及spring 的jpa实现
??spring-oxm:Spring对于object/xml映射的支持,可以让JAVA与XML之间来回切换
??spring-test:对JUNIT等测试框架的简单封装
??spring-tx:为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理。
??spring-web:包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。
??spring-webmvc:包含SpringMVC框架相关的所有类。包含国际化、标签、Theme、视图展现的FreeMarker、JasperReports、 Tiles、Velocity、XSLT相关类。当然,如果你的应用使用了独立的MVC框架,则无需这个JAR文件里的任何类。
??spring-webmvc-portlet:Spring MVC的增强
??spring-websocket:提供 Socket通信, web端的推送功能
导入IOC相关jar包
spring-beans-4.3.24.RELEASE.jar
spring-context-4.3.24.RELEASE.jar
spring-context-support-4.3.24.RELEASE.jar
spring-core-4.3.24.RELEASE.jar
spring-expression-4.3.24.RELEASE.jar
日志包
commons-logging-1.2.jar
log4j-1.2.17.jar
log4j-api-2.11.2.jar
log4j-core-2.11.2.jar
Spring配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!-- 注册一个类的对象 -->
<bean id="user" class="com.sxt.bean.User" />
</beans>
测试程序
package com.sxt.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.sxt.bean.User;
public class Test {
public static void main(String[] args) {
// 引入配置文件 读取配置信息
ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
//new User()
// 此时使用 spring 容器 : 根据指定的类,就可以获取这个类的对象
// 说明容器中,本身就存在这个对象,那么一定有人创建了对象,创建人不是程序员,是Spring
// 此时 创建对象的权利,从开发者的手中,移交到Spring框架.这就是IOC (控制反转)
// 创建对象,控制对象的生命周期的角色发生反转,所以被称之为控制反转
// 从Spring IOC容器中获取对象
User bean = context.getBean(User.class);
// 使用对象调用方法
bean.study();
System.out.println(bean);
User bean2 = context.getBean(User.class);
System.out.println(bean2);
}
}
???使用构造器创建Bean对象,必须要有无参构造方法
<!--
id : bean标签唯一标识 也是对象唯一标识 一个bean只有一个ID值且整个IOC容器ID值不允许重复
name : bean标签中name属性,也是对象的name值,name值可以多个,使用逗号分隔.当name值没有时,id值就是name值
class : 需要创建对象的类
-->
<bean id="user" name="user1,user2,user3" class="com.sxt.bean.User" />
<!--
方式二: 使用静态工厂方式
class : 工厂类
factory-method : 工厂方法
-->
<bean id="userFactory" class="com.sxt.factory.UserFactory" factory-method="getUser"></bean>
package com.sxt.factory;
import com.sxt.bean.User;
public class UserFactory {
public static User getUser() {
return new User();
}
}
<!--
方式三: 非静态工厂
factory-bean : 工厂对象
factory-method : 工厂方法
-->
<!-- 创建工厂对象,用于调用工厂中非静态的方法 -->
<bean id="userDyFactory" class="com.sxt.factory.UserDyFactory"></bean>
<!-- 根据工厂对象,工厂方法创建Bean对象 -->
<bean id="userBean" factory-bean="userDyFactory" factory-method="getUser"></bean>
package com.sxt.factory;
import com.sxt.bean.User;
public class UserDyFactory {
/**
* 非静态方法
*/
public User getUser() {
return new User();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!--
创建对象 : 无参构造方法
-->
<bean id="user1" class="com.sxt.bean.User"></bean>
<!-- 创建对象: 2个参数的构造方法 -->
<bean id="user2" class="com.sxt.bean.User">
<constructor-arg index="0" value="韩梅梅"></constructor-arg>
<constructor-arg index="1" value="女"></constructor-arg>
</bean>
<!-- 创建对象: 3个参数的构造方法 -->
<bean id="user3" class="com.sxt.bean.User">
<constructor-arg index="0" value="韩梅梅"></constructor-arg>
<constructor-arg index="1" value="女"></constructor-arg>
<constructor-arg index="2" value="18"></constructor-arg>
</bean>
<!-- 创建对象: 构造方法 参数名称注入属性值 -->
<bean id="user4" class="com.sxt.bean.User">
<constructor-arg name="name" value="韩梅梅"></constructor-arg>
<constructor-arg name="sex" value="女"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
</bean>
</beans>
package com.sxt.bean;
public class User {
// private String name;
// private String sex;
// private Integer age;
private String name1;
private String sex1;
private Integer age1;
public User() {
System.out.println("我是无参构造方法");
}
public User(String name, String sex) {
this.name1 = name;
this.sex1 = sex;
}
public User(String name, String sex, Integer age) {
this.name1 = name;
this.sex1 = sex;
this.age1 = age;
}
public void study() {
System.out.println("我是学习方法");
}
public String getName() {
return name1;
}
public void setName(String name) {
this.name1 = name;
}
public String getSex() {
return sex1;
}
public void setSex(String sex) {
this.sex1 = sex;
}
public Integer getAge() {
return age1;
}
public void setAge(Integer age) {
this.age1 = age;
}
@Override
public String toString() {
return "User [name=" + name1 + ", sex=" + sex1 + ", age=" + age1 + "]";
}
}
<!--
方式二: 使用set方法注入属性
此时的name 值 不是真的类中属性名 只 set方法中setXxx中xxx
-->
<bean id="user5" class="com.sxt.bean.User">
<property name="name" value="韩梅梅"></property>
<property name="sex" value="女"></property>
<property name="age" value="18"></property>
</bean>
package com.sxt.bean;
public class User {
private String name1;
private String sex1;
private Integer age1;
public User() {
System.out.println("我是无参构造方法");
}
public User(String name, String sex) {
this.name1 = name;
this.sex1 = sex;
}
public User(String name, String sex, Integer age) {
this.name1 = name;
this.sex1 = sex;
this.age1 = age;
}
public void study() {
System.out.println("我是学习方法");
}
public String getName() {
return name1;
}
public void setName(String name) {
this.name1 = name;
}
public String getSex() {
return sex1;
}
public void setSex(String sex) {
this.sex1 = sex;
}
public Integer getAge() {
return age1;
}
public void setAge(Integer age) {
this.age1 = age;
}
@Override
public String toString() {
return "User [name=" + name1 + ", sex=" + sex1 + ", age=" + age1 + "]";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!--
各种类型的属性的注入
-->
<!-- 1. 注入字符串 -->
<bean id="user1" class="com.sxt.bean.User">
<property name="str" value="我是字符串"></property>
</bean>
<!-- 2. 注入对象 方式一 -->
<bean id="st1" class="com.sxt.bean.Student">
<property name="name" value="韩梅梅"> </property>
<property name="sex" value="女"> </property>
</bean>
<!--
在注入属性值时,value 只能注入:基本数据类型和字符串,如果是对象,需要使用 ref 进行对相关联
-->
<bean id="user2" class="com.sxt.bean.User">
<property name="st" ref="st1" >
</property>
</bean>
<!-- 注入对象方式二 -->
<bean id="user3" class="com.sxt.bean.User">
<property name="st">
<bean class="com.sxt.bean.Student">
<property name="name" value="韩梅梅"> </property>
<property name="sex" value="女"> </property>
</bean>
</property>
</bean>
<!--3 .注入数组结构 -->
<bean id="user4" class="com.sxt.bean.User">
<property name="list1">
<array>
<value>韩梅梅</value>
<value>李磊</value>
<value>Jim</value>
<value>Lucy</value>
</array>
</property>
</bean>
<!-- list结构属性 -->
<bean id="user5" class="com.sxt.bean.User">
<property name="list1">
<list>
<value>韩梅梅</value>
<value>李磊</value>
<value>Jim</value>
<value>Lucy</value>
</list>
</property>
</bean>
<bean id="user6" class="com.sxt.bean.User">
<property name="list2">
<list>
<bean class="com.sxt.bean.Student">
<property name="name" value="韩梅梅"></property>
<property name="sex" value="女"></property>
</bean>
<bean class="com.sxt.bean.Student">
<property name="name" value="Lucy"></property>
<property name="sex" value="女"></property>
</bean>
<ref bean="st1"/>
</list>
</property>
</bean>
<!-- set结构属性 -->
<bean id="user7" class="com.sxt.bean.User">
<property name="set1">
<set>
<value>字符串1</value>
<value>字符串2</value>
<value>字符串3</value>
<value>字符串1</value>
<value>字符串1</value>
</set>
</property>
</bean>
<bean id="user8" class="com.sxt.bean.User">
<property name="set2">
<set>
<bean class="com.sxt.bean.Student">
<property name="name" value="韩梅梅"></property>
<property name="sex" value="女"></property>
</bean>
<bean class="com.sxt.bean.Student">
<property name="name" value="Lucy"></property>
<property name="sex" value="女"></property>
</bean>
<ref bean="st1"/>
</set>
</property>
</bean>
<!-- map结构 -->
<bean id="user9" class="com.sxt.bean.User">
<property name="map1">
<map>
<entry key="key1" value="value1"></entry>
<entry key="key2" value="value2"></entry>
<entry key="key3" value="value3"></entry>
<entry key="key4" value="value4"></entry>
</map>
</property>
</bean>
<bean id="user10" class="com.sxt.bean.User">
<property name="map2">
<map>
<entry key="key1" value-ref="st1"></entry>
<entry key="key2" >
<bean class="com.sxt.bean.Student">
<property name="name" value="韩梅梅"></property>
<property name="sex" value="女"></property>
</bean>
</entry>
</map>
</property>
</bean>
<!-- properties 对象 -->
<bean id="user11" class="com.sxt.bean.User">
<property name="prop">
<props>
<prop key="key1">value1</prop>
<prop key="key2">value2</prop>
<prop key="key3">value3</prop>
</props>
</property>
</bean>
</beans>
package com.sxt.bean;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class User {
private String str; // 字符串
private Student st; // 对象
private List<String> list1; //list集合
private List<Student> list2; //list集合
private Set<String> set1; //set集合
private Set<Student> set2; //set集合
private Map<String,String> map1; // Map
private Map<String,Student> map2; // Map
private Properties prop; // properties
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public Student getSt() {
return st;
}
public void setSt(Student st) {
this.st = st;
}
public List<String> getList1() {
return list1;
}
public void setList1(List<String> list1) {
this.list1 = list1;
}
public List<Student> getList2() {
return list2;
}
public void setList2(List<Student> list2) {
this.list2 = list2;
}
public Set<String> getSet1() {
return set1;
}
public void setSet1(Set<String> set1) {
this.set1 = set1;
}
public Set<Student> getSet2() {
return set2;
}
public void setSet2(Set<Student> set2) {
this.set2 = set2;
}
public Map<String, String> getMap1() {
return map1;
}
public void setMap1(Map<String, String> map1) {
this.map1 = map1;
}
public Map<String, Student> getMap2() {
return map2;
}
public void setMap2(Map<String, Student> map2) {
this.map2 = map2;
}
public Properties getProp() {
return prop;
}
public void setProp(Properties prop) {
this.prop = prop;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!--
注意:
在spring中,默认会根据配置文件创建对象放入到ioc容器中
lazy-init : 是否懒加载 default/false : 不进行懒加载 ,程序启动加载对象.true 进行懒加载,只有使用时才加载
scope : 对象作用域
singleton : 单例 默认
prototype : 非单例
request : 每次请求创建对象
session : 每次会话
init-method :
初始化方法 对象创建后进行对象初始化调用的方法
destroy-method :
ioc容器中,对象销毁时调用的方法
autowire :自动装配对象属性
byType : 根据类型装配
byName : 根据属性的name装配
autowire-candidate : 是否被自动装配查找
true : 可以被自动装配 默认
false : 不可以被自动装配
primary :
在装配时,推荐使用的
abstract : 是否是抽象类
parent : 父级,可以进行属性继承
depends-on : 依赖的Bean
-->
<bean id="user1" class="com.sxt.bean.User" scope="singleton" init-method="init" destroy-method="destory" depends-on="st" ></bean>
<bean id="st" class="com.sxt.bean.Student" autowire-candidate="default" >
<property name="name" value="韩梅梅"></property>
<property name="sex" value="18"></property>
</bean>
</beans>
pojo
package com.sxt.pojo;
public class User {
private String name;
private Integer age;
public User() {}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}
dao
package com.sxt.dao;
import java.util.List;
import com.sxt.pojo.User;
public interface IUserDao {
public List<User> selectAll();
}
dao.impl
package com.sxt.dao.impl;
import java.util.ArrayList;
import java.util.List;
import com.sxt.dao.IUserDao;
import com.sxt.pojo.User;
public class UserDaoImpl implements IUserDao{
@Override
public List<User> selectAll() {
System.out.println("dao 层 selectAll");
List<User> list = new ArrayList<User>();
list.add(new User("韩梅梅", 18));
list.add(new User("Lucy", 18));
list.add(new User("Lily", 18));
return list;
}
}
service
package com.sxt.service;
import java.util.List;
import com.sxt.pojo.User;
public interface IUserService {
public List<User> queryAll();
}
service.impl
package com.sxt.service.impl;
import java.util.List;
import com.sxt.dao.IUserDao;
import com.sxt.pojo.User;
import com.sxt.service.IUserService;
public class UserServiceImpl implements IUserService {
private IUserDao userDao;
@Override
public List<User> queryAll() {
return userDao.selectAll();
}
public void setUserDao(IUserDao userDao) {
this.userDao = userDao;
}
}
controller
package com.sxt.controller;
import java.util.List;
import com.sxt.pojo.User;
import com.sxt.service.IUserService;
public class UserController {
private IUserService userService;
public void list() {
List<User> users = userService.queryAll();
for (User user : users) {
System.out.println(user);
}
}
public void setUserService(IUserService userService) {
this.userService = userService;
}
}
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!-- 配置Dao 层 -->
<bean id="userDao" class="com.sxt.dao.impl.UserDaoImpl"></bean>
<!-- 配置Service -->
<bean id="userService" class="com.sxt.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
<!-- 配置controller -->
<bean id="userController" class="com.sxt.controller.UserController">
<property name="userService" ref="userService"></property>
</bean>
</beans>
测试类:
package com.sxt.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.sxt.controller.UserController;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
UserController bean = context.getBean(UserController.class);
bean.list();
}
}
? 为了简化开发,Spring提供了一些内置注解:
? @Component:表示是一个组件,使用该注解修饰类,Spring自动为其创建对象,放入IOC容器
? @Service:继承于Component 注解,表示一个组件,主要用于Service层
? @Repository:继承于Component 注解,表示一个组件,主要用持久层
? @Controller:继承于Component 注解,表示一个组件,主要用于控制层
? @Autowired:用于为属性进行自动装配
? **@Qualifier(name)**:组件名称
spring-aop-4.3.24.RELEASE.jar
aop约束
context约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
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 https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 扫描注解组件,使其生效 -->
<context:component-scan base-package="com.sxt.dao.impl,com.sxt.service.impl,com.sxt.controller"></context:component-scan>
<!-- 包下面所有的类都要进行扫描 -->
<!-- <context:component-scan base-package="com.sxt"></context:component-scan> -->
</beans>
???Spring的IoC是管理对象,使用AOP管理方法。如何管理方法,扩展方法,如何扩展方法?方法中套方法,装饰者模式。
???但是装饰者模式,需要类与类之间存在关系.提高了程序耦合读,不便于维护和扩展.基于这个原因,开发者提出了AOP的想法,面向切面编程 ----- 横向扩展程序.这种扩展方式,也被称之为拔插式的扩展,需要使用时,只需要织入想要扩展的内容,不需要时,只需要取消织入. 具体的实现,依赖动态代理模式,相对于纵向扩展,编码的复杂度高一些,但是代码灵活一些。
??开启事务
??关闭事务
??回滚事务
??将请求信息进行持久化.发生请求信息获得方式都一样,只需要将请求对象统一保存.数据分析.
???代理,代替打理。
package com.sxt.target;
/**
* 被代替的类
*/
public class TargetClass {
public void sing() {
System.out.println(" 世上只有妈妈好 ");
}
}
package com.sxt.target;
/**
* 代理类
*/
public class ProxyClass {
// 被代理的对象
TargetClass targetClass;
public ProxyClass(TargetClass targetClass) {
super();
this.targetClass = targetClass;
}
public void sing() {
System.out.println("查看行程计划");
System.out.println("确定时间");
System.out.println("修改行程计划");
System.out.println("下周二");
targetClass.sing();
}
}
package com.sxt.target;
public class Test {
public static void main(String[] args) {
// 被代理的对象
TargetClass targetClass = new TargetClass();
// 创建代理类
ProxyClass proxyClass = new ProxyClass(targetClass);
//调用方法
proxyClass.sing();
}
}
静态代理的不足:
???必须定义代理类,且代理的方法声明了,扩展性相对较差.类和类之间产生了关系,耦合性加强了.不便于维护 ,代码的可读性也会降低。
??动态的为需要代理的类,创建一个具体的代理类.不再需要开发者定义具体的代理的类.这种方式,就是动态代理.JDK为此制定了一个标准.
类: Proxy代理类,所有代理的类基类
???Proxy
提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类.
??newProxyInstance(ClassLoader loader, Class<?>... interfaces,InvocationHandler hanlder) : 类加载器 当前类的加载器,interfaces 接口的Class对象 hanlder 代理类的处理器
??接口:InvocationHandler 与代理类关联调用程序的处理器
package com.sxt.target;
/**
* 配置类
*/
public class Config {
//开启事务的方法的名称的前缀
public static String[] preFix = {"add","update","delete"};
}
package com.sxt.target;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 代理类绑定的代理处理器
*/
public class ProxyHanlder implements InvocationHandler {
// 被代理的目标 此时类型时 Object 那么传入任何类型都可以
private Object proxyTarget;
public ProxyHanlder(Object proxyTarget) {
this.proxyTarget = proxyTarget;
}
/**
* proxy : ProxyHanlder 对象 代理处理器对象
* method : 被代理调用的方法
* args : 方法中参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
for (String name : Config.preFix) {
if(methodName.startsWith(name)) {
new TransctionManager().beginTrancation();
}
}
Object obj = method.invoke(proxyTarget, args);
for (String name : Config.preFix) {
if(methodName.startsWith(name)) {
new TransctionManager().commitTrancation();
}
}
return obj;
}
}
package com.sxt.target;
/**
* @ClassName: TargetClassInteterface
* @Description: 被代理的类的接口
* @author: Mr.T
* @date: 2019年11月22日 上午11:14:03
*/
public interface TargetClassInteterface {
public void addUser(String name) ;
public void deleteUser() ;
public void updateUser() ;
public void selectUser() ;
}
package com.sxt.target;
/**
* @ClassName: TargetClass
* @Description: 具体的代理类
* @author: Mr.T
* @date: 2019年11月22日 上午11:15:19
*/
public class TargetClass implements TargetClassInteterface {
@Override
public void addUser(String name) {
System.out.println("新增用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
@Override
public void updateUser() {
System.out.println("修改用户");
}
@Override
public void selectUser() {
System.out.println("查询用户");
}
}
package com.sxt.target;
/**
* @ClassName: TransctionManager
* @Description: 事务管理器 增强的具体内容
* @author: Mr.T
* @date: 2019年11月22日 上午11:35:37
*/
public class TransctionManager {
public void beginTrancation() {
System.out.println("开启事务");
}
public void commitTrancation() {
System.out.println("提交事务");
}
}
package com.sxt.target;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
// 生成代理编译后的文件
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
// 创建了被代理的目标
TargetClassInteterface targetInterface = new TargetClass();
// 创建代理类的处理器
ProxyHanlder proxyHandler = new ProxyHanlder(targetInterface);
// 创建代理类
TargetClassInteterface proxyObj = (TargetClassInteterface) Proxy.newProxyInstance(Test.class.getClassLoader(), new Class[] {TargetClassInteterface.class}, proxyHandler);
proxyObj.addUser("user");
System.out.println("======================");
proxyObj.deleteUser();
System.out.println("======================");
proxyObj.updateUser();
System.out.println("======================");
proxyObj.selectUser();
System.out.println("======================");
}
}
不足:
package com.sun.proxy;
import com.sxt.target2.TargetClassInteterface;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
// 生成的代理类 $Proxy0 是 Proxy 子类且是 TargetClassInteterface 实现类
// 那么这个代理类就要有 TargetClassInteterface 里面抽象方法
public final class $Proxy0 extends Proxy implements TargetClassInteterface {
private static Method m0; // ======> Object类中的 hashCode
private static Method m1; // ======> Object类中的 equals
private static Method m2; // ======> Object类中的 toString
private static Method m3; // ======> 实现了接口中 addUser 方法
static
{
try {
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m3 = Class.forName("com.sxt.target2.TargetClassInteterface").getMethod("addUser", new Class[] { Class.forName("java.lang.String") });
return;
}
catch (NoSuchMethodException localNoSuchMethodException) {
throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
}
catch (ClassNotFoundException localClassNotFoundException) {
throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
}
}
// 创建代理类对象 InvocationHandler 对象 本质上就是传入 ProxyHanlder 自己定义的代理类程序处理器
public $Proxy0(InvocationHandler paramInvocationHandler)
throws
{
// 调用父类的有参构造方法 : 将自己定义 ProxyHanlder 传给Proxy
super(paramInvocationHandler);
// 将自己定义的处理器 赋值给了 Proxy 类中 h 成员变量
}
public final boolean equals(Object paramObject)
throws
{
try
{
return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
// 在测试类中,使用创建出来的代理对象 调用 addUser ,其实就是调用此处的addUser
public final void addUser(String paramString)
throws
{
try
{
// this.h : ProxyHandler对象
// this.h 当前类中h变量 当前类中没有 h 所以h是从父类 Proxy类继承而来.
// this.h 就是父类Proxy中h,而Proxy中h ,是自定义的ProxyHandler
// proxyHandler.invoke(this,m3,paramString); //this : proxy 代理类对象 m3 具体的add方法 paramString 传入的参数
// 调用Proxy Handler的 invoke 方法
/*
// 被代理的目标 此时类型时 Object 那么传入任何类型都可以
private Object proxyTarget;
public ProxyHanlder(Object proxyTarget) {
this.proxyTarget = proxyTarget;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
beginTrancation(); // 开启事务
//m3 addUser.invoke(obj ,args ) : // 此时的obj :proxyTarget ----> 被代理的具体目标类对象 addUser(String name) { 新增用户 }
Object obj = method.invoke(proxyTarget, args);
commitTrancation();
return obj;
}
*/
this.h.invoke(this, m3, new Object[] { paramString });
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final String toString()
throws
{
try
{
return (String)this.h.invoke(this, m2, null);
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final int hashCode()
throws
{
try
{
return ((Integer)this.h.invoke(this, m0, null)).intValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
}
JDK动态代理的不足:
??结构相对复杂,必须依赖接口.被代理的对象要有接口(接口要当做参数传递).其二,其本质是使用的反射,执行效率相对而言较低.
由于以上原因,Cglib出现,解决以上问题.
??问题1:必须要有接口,没有接口如何实现动态代理?
?????既然没有接口,那么使用子类,使用继承。
???问题2:利用反射执行效率低,如何解决效率低?
????执行效率低,创建对象,低在方法查找。那么将需要代理的方法创建好,存储在容器中,需要使用时,根据方法对应的索引,找到方法.。
导入jar包
asm-7.0.jar
cglib-3.2.10.jar
编写代码
目标类
package com.target;
/**
* 被代理的类
*/
public class TargetClass {
public void sing() {
System.out.println("唱歌");
}
}
增强类
package com.target;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* 方法拦截器
*/
public class MyMethodIntercepter implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
before();
// obj : 子类对象 ----父类 TargetClass
// args : 参数
// cglib的动态代理 不是反射. 使用 索引找到该方法
Object rs = proxy.invokeSuper(obj, args);
after();
return rs;
}
public void before() {
System.out.println("前置增强");
}
public void after() {
System.out.println("后置增强");
}
}
创建代理类:
package com.target;
import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.proxy.Enhancer;
public class Test {
public static void main(String[] args) {
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D://java");
// 创建增强器
Enhancer enhancer = new Enhancer();
// 增强的目标
enhancer.setSuperclass(TargetClass.class);
// 使用谁增强
enhancer.setCallback(new MyMethodIntercepter());
// 创建代理类
TargetClass obj = (TargetClass) enhancer.create();
// 调用方法
obj.sing();
}
}
package com.target;
import java.lang.reflect.InvocationTargetException;
import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.reflect.FastClass;
public class Test2 {
public static void main(String[] args) {
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D://java");
FastClass create = FastClass.create(TargetClass.class);
//获取方法的索引
int index = create.getIndex("sing", new Class[] {});
//调用方法
try {
create.invoke(index, new TargetClass(), null);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
Cglib动态代理的不足
导入jar包
aspectjweaver.jar
commons-logging-1.2.jar
log4j-1.2.17.jar
log4j-api-2.11.2.jar
log4j-core-2.11.2.jar
spring-aspects-4.3.24.RELEASE.jar
spring-beans-4.3.24.RELEASE.jar
spring-context-4.3.24.RELEASE.jar
spring-context-support-4.3.24.RELEASE.jar
spring-core-4.3.24.RELEASE.jar
spring-expression-4.3.24.RELEASE.jar
编写代码
被增强的目标
package com.sxt.target;
/**
* 目标类接口
*/
public interface ITargetClass {
/**
* 唱歌方法
*/
public void sing();
}
package com.sxt.target.impl;
import com.sxt.target.ITargetClass;
public class TargetClassImpl implements ITargetClass{
@Override
public void sing() {
int m = 0;
System.out.println(1/m);
System.out.println(" 月亮代表我的心 ");
}
}
增强类:
package com.sxt.advice;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class BeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("前置增强");
}
}
package com.sxt.advice;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
/**
* 后置增强类
*/
public class AfterAdvice implements AfterReturningAdvice{
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("后置增强");
}
}
package com.sxt.advice;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
* 环绕增强
*/
public class RoundAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
//调用前置增强
beforeAdvice();
//目标方法执行
Method method = invocation.getMethod(); //目标方法
Object[] arguments = invocation.getArguments(); //目标方法的参数
//执行当前目标方法
Object rs = invocation.proceed();
afterAdvice();
return rs;
}
public void beforeAdvice() {
System.out.println("前置增强");
}
public void afterAdvice() {
System.out.println("后置增强");
}
}
package com.sxt.advice;
import org.springframework.aop.ThrowsAdvice;
public class ExceptionAdvice implements ThrowsAdvice{
/**
* 方法名必须为afterThrowing 且要有 Throwable 参数
*/
public void afterThrowing(Throwable th) {
System.out.println("我是异常增强,发生异常时我执行");
}
}
aop配置
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置增强的目标 -->
<bean id="targetClass" class="com.sxt.target.impl.TargetClassImpl"></bean>
<!-- 具体增强类对象 -->
<!-- 前置增强 -->
<bean id="beforeAdvice" class="com.sxt.advice.BeforeAdvice"></bean>
<!-- 后置增强 -->
<bean id="afterAdvice" class="com.sxt.advice.AfterAdvice"></bean>
<!-- 环绕增强 -->
<bean id="roundAdvice" class="com.sxt.advice.RoundAdvice"></bean>
<!-- 异常增强 -->
<bean id="exceptionAdvice" class="com.sxt.advice.ExceptionAdvice"></bean>
<!-- 织入: 将切点 和 具体增强类结合 -->
<!-- 进行AOP配置 -->
<aop:config>
<!-- 配置切入点 : 需要增强的方法 -->
<aop:pointcut expression="execution(* com.sxt.target.impl.TargetClassImpl.*(..))" id="pointcut" />
<!-- 配置切面方法 -->
<!-- <aop:advisor advice-ref="beforeAdvice" pointcut-ref="pointcut"/> -->
<!-- <aop:advisor advice-ref="afterAdvice" pointcut-ref="pointcut"/> -->
<!-- <aop:advisor advice-ref="roundAdvice" pointcut-ref="pointcut"/> -->
<aop:advisor advice-ref="exceptionAdvice" pointcut-ref="pointcut" />
</aop:config>
</beans>
测试:
package com.sxt.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.sxt.target.ITargetClass;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
ITargetClass obj = (ITargetClass) context.getBean("targetClass");
obj.sing();
}
}
? AspectJ是一个基于Java语言的AOP框架,Spring2.0开始引入对AspectJ的支持,AspectJ扩展了Java语言,提供了专门的编译器,在编译时提供了横向代码的注入。
? @AspectJ是AspectJ1.5新增功能,通过JDK1.5注解技术,允许直接在Bean中定义切面
? 新版本的Spring中,建议使用AspectJ方式开发AOP
编写目标类:
package com.sxt.target;
/**
* 目标类接口
*/
public interface ITargetClass {
/**
* 唱歌方法
*/
public void sing();
}
package com.sxt.target.impl;
import com.sxt.exception.MyException;
import com.sxt.target.ITargetClass;
public class TargetClassImpl implements ITargetClass{
@Override
public void sing() {
throw new MyException("4001001", "自己定义的异常");
// System.out.println("");
}
}
增强类:
package com.sxt.advice;
import org.aspectj.lang.ProceedingJoinPoint;
import com.sxt.exception.MyException;
/**
* 增强类
*/
public class MyAdvice {
public void beforeAdvice() {
System.out.println("前置增强");
}
public void afterAdvice() {
System.out.println("后置增强");
}
public void roundAdvice(ProceedingJoinPoint pjp) {
beforeAdvice();
// 获取参数
Object[] args = pjp.getArgs();
// 增强的目标方法
Object target = pjp.getTarget();
try {
Object proceed = pjp.proceed();
afterAdvice();
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 可以做异常拦截
*/
public void exceptionAdvice(Throwable tx) {
if (tx instanceof MyException) {
MyException myException = (MyException) tx;
System.out.println(myException.getCode());
System.out.println(myException.getMsg());
return;
}
System.out.println(tx);
System.out.println("异常增强");
}
}
xml配置
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置增强的目标 -->
<bean id="targetClass" class="com.sxt.target.impl.TargetClassImpl"></bean>
<!-- 具体增强类对象 -->
<bean id="myAdvice" class="com.sxt.advice.MyAdvice"></bean>
<!--
织入: 将切点 和 具体增强类结合
-->
<!-- 进行AOP配置 -->
<aop:config>
<!-- 配置增强对象 -->
<aop:aspect ref="myAdvice">
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* com.sxt.target.impl.*.*(..))" id="pointcut"/>
<!-- 配置增强对象中方法 前置增强 -->
<!-- <aop:before method="beforeAdvice" pointcut-ref="pointcut" /> -->
<!-- 后置增强 -->
<!-- <aop:after method="afterAdvice" pointcut-ref="pointcut"/> -->
<!-- 环绕增强 -->
<!-- <aop:around method="roundAdvice" pointcut-ref="pointcut"/> -->
<!-- 异常增强 -->
<aop:after-throwing method="exceptionAdvice" pointcut-ref="pointcut" throwing="tx"/>
</aop:aspect>
</aop:config>
</beans>
增强类:
package com.sxt.advice;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import com.sxt.exception.MyException;
/**
* 增强类
*/
@Component
@Aspect
public class MyAdvice {
// @Before("execution(* com.sxt.target.impl.*.*(..))")
public void beforeAdvice() {
System.out.println(this);
System.out.println("前置增强");
}
/**
* @AfterReturning 可以拿到 目标方法的返回值
* @After 只能后置增强的效果
*/
@AfterReturning(value="execution(* com.sxt.target.impl.*.*(..))",returning = "rs")
public void afterAdvice(Object rs) {
System.out.println(rs);
System.out.println("后置增强");
}
// execution(* 包名.类.方法(..) ..:表示任意参数
// @Around("execution(* com.sxt.target.impl.*.*(..))")
public void roundAdvice(ProceedingJoinPoint pjp) {
beforeAdvice();
// 获取参数
Object[] args = pjp.getArgs();
// 增强的目标方法
Object target = pjp.getTarget();
try {
Object proceed = pjp.proceed();
//afterAdvice();
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* 可以做异常拦截
*/
// @AfterThrowing( value="execution(* com.sxt.target.impl.*.*(..))",throwing = "tx")
public void exceptionAdvice(Throwable tx) {
if(tx instanceof MyException) {
MyException myException = (MyException) tx;
System.out.println(myException.getCode());
System.out.println(myException.getMsg());
return ;
}
System.out.println(tx);
System.out.println("异常增强");
}
}
目标类:
package com.sxt.target.impl;
import org.springframework.stereotype.Component;
import com.sxt.exception.MyException;
import com.sxt.target.IUserDao;
@Component
public class UserDaoImpl implements IUserDao {
@Override
public int sing() {
//throw new MyException("4001001", "自己定义的异常");
System.out.println(" 月亮代表我的心 ");
return 10;
}
}
xml配置
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 扫描组件 -->
<context:component-scan base-package="com.sxt"></context:component-scan>
<!-- 开启注解式 增强的通知
proxy-target-class 使用cglib 创建代理对象
1. UserDao 创建代理对象
2. 增强类绑定
默认是JDK 的代理动态代理 === UserDaoImpl 代理类
-->
<aop:aspectj-autoproxy proxy-target-class="true" ></aop:aspectj-autoproxy>
</beans>
IoC/DI和AOP
IoC : 控制反转
??对于整个应用而言,创建对象的权利,从应用自身创建移交给了Spring容器.对象的创建的权利发生转向.所以被称之为控制反转.
DI : 依赖注入
??在研究控制反转时,发现其实反转的内容主要只,对象创建和对象注入.且对象的创建存在依赖关系.所以,控制反转其实更具体就是注入对象.所以被称之为DI.
??控制反转和依赖注入本质上一样的,但是角度不同.站在应用的角度,是控制反转,站在Spring容器的角度上,是依赖注入.
创建对象
创建对象的方式:
属性注入:
构造方法
set方法
注解
常用的注入方式:
??使用set方法注入: 因为set方法可以根据需要的属性进行注入,而构造方法依赖构造器.必须要有set方法.
??注解(最常用),一般只能用于自己定义的代码.在源码中无法使用注解.
IOC常用注解:
??@Component : 组件 被该注解注释的类, 会创建对象对象放入到IOC容器
??@Controller : 表示控制层 被该注解注释的类, 会创建对象对象放入到IOC容器
??@Service : 表示Service 层 被该注解注释的类, 会创建对象对象放入到IOC容器
??@Repository : 表示持久化层 被该注解注释的类, 会创建对象对象放入到IOC容器
??@Autowired : 自动装配 默认type装配
??@Qualifier(名称) : 使用指定的名称装配对象
注意:
???标准化.
???标准化,在开发中,在流程上会结构清晰,条理分明.代码可读性提高了.
??在维护上,定位问题相对快准确,扩展程序相对轻松
标签:NPU 说明 原因 tle update 介绍 邮件服务 定位 必须
原文地址:https://www.cnblogs.com/lyang-a/p/12563268.html