<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.3</version>
</dependency>
Spring开源的容器
Spring是轻量级和非入侵式
控制反转(IOC),面向切面编程(AOP)
支持事务的处理,对框架的整合支持
SpringBoot
快速开发,约定大于配置
SpringCloud
基于SpringBoot实现
使用Set接口实现
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
解决创建对象的问题,耦合性降低
IOC本质:设计思想,DI(依赖注入)是一种实现方式,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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--spring创建对象
UserDaoMysqlImpl mysqlImpl = new UserDaoMysqlImpl()
id = 变量名
class = new 的对象
property 相当于给对象中的属性设置一个值
-->
<bean id = "mysqlImpl" class="com.liu.dao.UserDaoMysqlImpl"/>
<bean id = "oracleImpl" class="com.liu.dao.UserDaoOracleImpl"/>
<bean id = "sqlServermpl" class="com.liu.dao.UserDaoSqlServermpl"/>
<bean id="UserServiceImpl" class="com.liu.service.UserServiceImpl">
<!--ref: 引用spring容器创建的对象
value: 具体的值,基本数据类型
-->
<property name="userDao" ref="sqlServermpl"/>
</bean>
</beans>
测试代码
import com.liu.service.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
UserServiceImpl userServiceImpl = (UserServiceImpl)applicationContext.getBean("UserServiceImpl");
userServiceImpl.getUser();
}
}
使用无参构造创建对象
<bean id="user" class="com.liu.pojo.User">
<property name="name" value="测试"/>
</bean>
使用有参构造创建对象
下标赋值
<!--1.下标赋值-->
<bean id="user" class="com.liu.pojo.User">
<constructor-arg index="0" value="测试"/>
</bean>
参数类型赋值
<!--2.参数类型赋值,不建议使用-->
<bean id="user" class="com.liu.pojo.User">
<constructor-arg type="java.lang.String" value="测试"/>
</bean>
参数名赋值
<!--3.通过参数名设置-->
<bean id="user" class="com.liu.pojo.User">
<constructor-arg name="name" value="测试"/>
</bean>
总结:在配置文件加载时,容器中管理的对象就创建了
<!--别名,添加别名可以利用别名获取对象-->
<alias name="user" alias="abc"/>
<!--
id: bean的唯一标识符,对象名
class: bean对象对应的全限定名: 包名+类型
name: 也是别名,可以取多个别名
-->
<bean id="userT" class="com.liu.pojo.UserT" name="user2, u2">
<property name="name" value="12"/>
</bean>
利用import将所有人的配置合并成一个总的配置
<import resource="beans.xml"/>
参考前面方法
依赖:bean对象的创建依赖容器
注入:bean对象的所有属性,由容器来注入
对象
public class Address {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
实际对象
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobbys;
private Map<String, String> card;
private Set<String> games;
private Properties info;
private String wife;
}
配置项
<?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="student" class="com.liu.pojo.Student">
<!--第一种,普通值注入,value-->
<property name="name" value="测试"/>
</bean>
</beans>
测试类
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = (Student)context.getBean("student");
System.out.println(student.getName());
}
}
注入信息
<?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="address" class="com.liu.pojo.Address"/>
<bean id="student" class="com.liu.pojo.Student">
<!--第一种,普通值注入,value-->
<property name="name" value="测试"/>
<!--第二种,对象注入,ref-->
<property name="address" ref="address"/>
<!--数组注入-->
<property name="books">
<array>
<value>西游记</value>
<value>三国演义</value>
<value>水浒传</value>
<value>红楼梦</value>
</array>
</property>
<!--list注入-->
<property name="hobbys">
<list>
<value>看书</value>
<value>打球</value>
<value>玩游戏</value>
</list>
</property>
<!--map注入-->
<property name="card">
<map>
<entry key="身份证" value="12344555"/>
<entry key="银行卡" value="24124412"/>
</map>
</property>
<!--set注入-->
<property name="games">
<set>
<value>LOL</value>
<value>CS</value>
</set>
</property>
<!--null-->
<property name="wife">
<null/>
</property>
<!--properties-->
<property name="info">
<props>
<prop key="driver">1234</prop>
<prop key="url">男</prop>
<prop key="username">root</prop>
<prop key="password">123445</prop>
</props>
</property>
</bean>
</beans>
p空间和c空间
三种装配的方式
<!--
byName: 会自动在容器上下文差再,和自己对象set方法后面的值对应的beanId(setDog, setCat)
byType: 会自动在容器上下文差再,和自己对象属性类型相同的bean
-->
<bean id="people" class="com.liu.pojo.People" autowire="byName">
<property name="name" value="无敌"/>
</bean>
总结:
使用注解:
导入约束
配置注解的支持<context:annotation-config/>
<?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"
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">
<context:annotation-config/>
</beans>
@Autowire
直接在属性上使用,也可也在set方法使用,可以省略set方法
@Nullable 字段标记这个注解,说明这个字段可以为Null
public @interface Autowired {
boolean required() default true;
}
测试代码
public class People {
//如果显示定义Autowired的required属性为false,说明这个对象可以为null,否则不允许为null
@Autowired(required = false)
private Cat cat;
@Autowired
private Dog dog;
private String name;
}
如果装配的环境比较复杂,自动装配无法通过一个注解完成,此时可以采用@Qualifer去配合@Autowired(使用byType)使用,指定一个唯一的bean对象注入
public class People {
@Autowired
@Qualifier(value = "cat111")
private Cat cat;
@Autowired
@Qualifier(value = "dog222")
private Dog dog;
}
@Resource注解
public class People {
@Resource(name = "cat11")
private Cat cat;
@Resource
private Dog dog;
小结:
@Resource和@Autowired
注解开发,必须保证AOP包导入
需要导入context约束
bean
属性注入
// 等价于 <bean id = "user" class = "com.liu.pojo.User"/>
// @Component 组件
@Component
public class User {
public String name;
// 相当于 <property name = "name" value = "测试"/>
@Value("测试")
public void setName(String name) {
this.name = name;
}
}
衍生的注解
@Component有几个衍生注解,按照mvc三层架构分层
dao 【@Repository】
service 【@Service】
controller 【@Controller】
这四个注解的功能一样,将类注册到spring中,装配Bean
作用域
@Component
@Scope("prototype")
public class User {
public String name;
// 相当于 <property name = "name" value = "测试"/>
@Value("测试")
public void setName(String name) {
this.name = name;
}
}
小结
xml与注解:
xml与注解:
使用Java来进行配置,JavaConfig在Spring4之后,推荐使用
实体类
public class User {
private String name;
public String getName() {
return name;
}
@Value("测试")
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name=‘" + name + ‘\‘‘ +
‘}‘;
}
}
配置文件
// 配置类也注册到容器中,类似于之前的xml文件
@Configuration
@ComponentScan("com.liu.pojo")
@Import(MyConfig2.class)
public class MyConfig {
//注册一个bean,就相当于我们之前的一个bean标签
//方法的名字就是Bean的id
//返回对象为Bean的class
@Bean
public User getUser() {
return new User();
}
}
测试类
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User user = (User)context.getBean("getUser");
System.out.println(user.getName());
}
}
这种纯java配置,在springboot很常见
代理模式分类:
角色分析:
代码步骤:
接口
//租房的接口
public interface Rent {
public void rent();
}
真实角色
//房东
public class Host implements Rent{
public void rent() {
System.out.println("房东要出租房子");
}
}
代理角色
public class Proxy implements Rent{
private Host host;
public Proxy(Host host) {
this.host = host;
}
public Proxy() {
}
public void rent() {
host.rent();
}
//看房
public void seeHouse() {
System.out.println("中介带你看房");
}
//收中介费
public void fare() {
System.out.println("中介收中介费");
}
//签合同
public void signContract() {
System.out.println("签约租赁合同");
}
}
客户访问代理角色
public class Client {
public static void main(String[] args) {
//房东要租房子
Host host = new Host();
//代理,中介帮房东租房子,代理角色有一些附属操作
Proxy proxy = new Proxy(host);
//你不用面对房东,直接找中介租房
proxy.rent();
}
}
代理模式的好处:
缺点:
了解两个类:Proxy:代理,InvocationHandler:调用处理程序
InvocationHandler
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Object target;
public void setTarget(Object target) {
this.target = target;
}
//生成得到代理类
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
//处理代理实例,并返回结果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动态代理的本质,就是使用反射机制实现
Object result = method.invoke(target, args);
return result;
}
}
动态代理的好处:
原文:https://www.cnblogs.com/tyroHeart/p/14443927.html