Spring的东西
- MAVEN的spring依赖
- spring的配置文件xml
- Maven的配置文件pom.xml打包错误问题(Source option 5 is no longer supported. Use 6 or later.)
- ApplicationContext的创建对象问题
- 神马是DI(依赖注入)
- spring标签
- 依赖注入bean标签
- 如何使用p-namespace
- XML配置文件中没有注册URI is not registered (Settings | Languages & Frameworks | Schemas and DTDs)
- Bean作用域
- 注解开发
- Spring框架的标签--@Autowired(自动装载)
- spring的扫描标签--@Component (扫描包中的类)
- spring的自动配置标签--@Bean (只能修饰方法)
- AOP如何使用
- 1.基于注解方式
- 2.xml方式配置
MAVEN的spring依赖
<!-- 1.Spring核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- 2.Spring dao依赖-->
<!-- spring-jdbc包括了一些如jdbcTemplate的工具类-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- 3.Spring web依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- 4.Spring test依赖:方便做单元测试和集成测试 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.7.RELEASE</version>
spring的配置文件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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
链接: link.
Maven的配置文件pom.xml打包错误问题(Source option 5 is no longer supported. Use 6 or later.)
**报这个错是因为你的本地开发jdk版本比你pom文件默认版本用的高。解决方法:在pom.xml文件中添加如下信息<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version><!--maven-compiler-plugin版本写一个中央仓库有的版本,保存后它会自动下载 -->
<configuration>
<source>11</source><!--我的jdk是10.0.1的,写成10.0.1不好用,所以就写成10了 -->
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
ApplicationContext的创建对象问题
ApplicationContext alc = new ClassPathXmlApplicationContext("beans.xml");
User userma = (User)alc.getBean("userma");
<--getBean只是调用User类的构造方法不会给他赋属性值除非是有参构造-->
userma.saying();
<--调用其他方法时会直接调用set方法给其赋值也就是property属性值注入-->
神马是DI(依赖注入)
**依赖容器注入属性**
在一个类中直接创建另一个类的对象的代码,,我们可以把这种坏味道称为硬初始化(hard init)。同时,我们也应该像记住硬编码一样记住,new(对象创建)是有毒的。不太好就。
public class MovieLister {
private MovieFinder finder;
public MovieLister() {
finder = new MovieFinderImpl();
}
}
//这种new对象的就不太好对
public class MovieLister {
private MovieFinder finder;
public MovieLister(MovieFinder finder) {
this.finder = finder;
}
}
//1.构造函数注入:这是我认为的最简单的依赖注入方式,我们修改一下上面代码中MovieList的构造函数,使得MovieFinderImpl的实现在MovieLister类之外创建。这样,MovieLister就只依赖于我们定义的MovieFinder接口,而不依赖于MovieFinder的实现了。
public class MovieLister {
public void setFinder(MovieFinder finder) {
this.finder = finder;
}
}
//2setter注入:类似的,我们可以增加一个setter函数来传入创建好的,就是把构造函数换了个名字
public interface InjectFinder {
void injectFinder(MovieFinder finder);
}
class MovieLister implements InjectFinder {
public void injectFinder(MovieFinder finder) {
this.finder = finder;
}
}
//3 接口注入:接口注入使用接口来提供setter方法,其实现方式如下。首先要创建一个注入使用的接口。
*最后需要注意的是,依赖注入只是控制反转的一种实现方式。控制反转还有一种常见的实现方式称为依赖查找。
spring标签
<bean id="userma" class="com.kpi.ma.User" name="userma2,userma3">
//id是唯一标识符,class是类全名,name是别名可以起很多个空格和逗号都可以分割
<property name="name" value="nerver"/>
</bean>
//别名
<alias name="userma" alias="mama"/>
//整合xml
<import resource="beans.xml"/>
<import resource="beans2.xml"/>
<import resource="beans3.xml"/>
依赖注入bean标签
<bean name="user1" class="com.kpi.ma.User">
</bean>
<bean id="student" class="com.kpi.ma.Student">
<!--一般数据类型-->
<property name="name" value="Tom"/>
<!--引用类型-->
<property name="user" ref="user1"/>
<!--array数组类型-->
<property name="srr" >
<array>
<value>java</value>
<value>c</value>
<value>c#</value>
<value>c++</value>
</array>
</property>
<!--list集合类型-->
<property name="pants">
<list>
<value>12</value>
<value>12</value>
<value>12</value>
</list>
</property>
<!--map类型-->
<property name="clothers">
<map>
<entry key="12" value="hhh"/>
<entry key="12" value="hhh"/>
<entry key="12" value="hhh"/>
</map>
</property>
<!--set类型-->
<property name="set">
<set>
<value>hi</value>
<value>hi</value>
<value>hi</value>
</set>
</property>
<!--Properties类型-->
<property name="info">
<props>
<prop key="sss"/>
</props>
</property>
</bean>
如何使用p-namespace
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3306/mydb"
p:username="root"
p:password="misterkaoli"/>
<bean id="myDataSource2" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
c:driverClassName="com.mysql.jdbc.Driver"
c:url="jdbc:mysql://localhost:3306/mydb"
c:username="root"
c:password="misterkaoli"/>
</beans>
//p是属性注入c是构造方法注入
XML配置文件中没有注册URI is not registered (Settings | Languages & Frameworks | Schemas and DTDs)
链接: link
Bean作用域
<bean id="userma3" class="com.kpi.ma.User" c:name="mom" c:age="133" scope="prototype"/>
<bean id="userma3" class="com.kpi.ma.User" c:name="mom" c:age="133" scope="singleton"/>
<!--默认spring中配置文件的bean帅哥单例模式(singleton)可以手动改为原型(prototype)-->
注解开发
1.@Autowired(自动装载通过类型,名字)可以根据其中属性值required=false来使修饰属性可以为空,如果不能自动装配可以与@Qualifier(value=“tom1”)一起使用而且两个条件需要都满足
2.@Nullable可以使修饰字段为可以空
3.@Resource自动装配通过名字,类型
4.@Component将组件放在类上说明该类被spring管理,相当于<bean id=“user” class="com.ma.pojo.User/>
5.@Value(“ma”)可以使用在属性或set方法上作为属性值的注入
@Value(“majingwei”)
private String name;
相当于// property name=“name” value=“ma”
6.dao层的Component叫@Repository他们的功能和Component一样都是等价的
7.service层的Component叫@Service
8.controller层的Component叫@Controller
8.@Scope(“prototype”)//原型放在类上面生成不一样的对象
@Scope(“singleton”)//单例模式
9.@Configuration作为纯java的配置类组件的标签也是Component
10.@ComponentScan(value=“com.ma.pojo”)扫描组件相当于配置文件中
<context:component- base-package=“com.ma.pojo”/>
//搜索组件
11.@Bean将方法变为bean对象,方法名为id返回值类型类位class
12.@import是整合java类配置bean相当于bean.xml中的import
13.前置通知:@Before 在目标业务方法执行之前执行
14后置通知:@After 在目标业务方法执行之后执行
15返回通知:@AfterReturning 在目标业务方法返回结果之后执行
16异常通知:@AfterThrowing 在目标业务方法抛出异常之后
17环绕通知:@Around 功能强大,可代替以上四种通知,还可以控制目标业务方法是否执行以及何时执行
Spring框架的标签–@Autowired(自动装载)
@Autowired( = false)
private Cat catma;
@Autowired
private Dog dogma;
<?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
https://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/>
<!--<bean id="cat" class="com.ma.pojo.Cat"/>-->
<!--<bean id="cat3" class="com.ma.pojo.Cat"/>-->
<bean id="dog1" class="com.ma.pojo.Dog"/>
<bean id="people" class="com.ma.pojo.People"/>
</beans>
//导入context命名空间及约束支持
xmlns:context="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
//并且开启注解支持
<context:annotation-config/>
//配置文件只需要导入bean即可
@Autowired注解可以在属性或者set方法上使用
@Autowired
private Dog dogma;
<bean id="dogma" class="com.ma.pojo.Dog"/>
<bean id="people" class="com.ma.pojo.People"/>
//在类中不用些set方法默认使用autowired的bytype方法如果找不到使用byName
@Autowired( = false)
private Cat catma;
<!--<bean id="cat" class="com.ma.pojo.Cat"/>-->
<!--<bean id="cat3" class="com.ma.pojo.Cat"/>-->
<bean id="dog1" class="com.ma.pojo.Dog"/>
<bean id="people" class="com.ma.pojo.People"/>
//在类中使用autowired的required(必须)值为false时可以为空属性不过不能只有有参的构造方法
@Autowired(required = false)
@Qualifier(value="cat3")
private Cat catma;
<bean id="cat" class="com.ma.pojo.Cat"/>
<bean id="cat3" class="com.ma.pojo.Cat"/>
<bean id="dog1" class="com.ma.pojo.Dog"/>
<bean id="people" class="com.ma.pojo.People"/>
//可以使用Qualifier指定实验的值若果autowired找不到合适的
spring的扫描标签–@Component (扫描包中的类)
@Component
public class User {
@Autowired
private Dog doo;
@Autowired(required = false)
private Cat caa;
}
//根据Component标签自动导入bean对象相当于
// < bean id=“user” class=“com.ma.pojo.User” />
spring的自动配置标签–@Bean (只能修饰方法)
@Configuration
@ComponentScan(value="com.ma.pojo")
@Import(User.class)
public class UserBean {
@Autowired
public User user;
@Bean(value = "user3")
public User getUser(){
return user;
}
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(UserBean.class);
User getUser = context.getBean("user3", User.class);
System.out.println(getUser.getName());
}
AOP如何使用
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
AOP的maven依赖↑↑↑
JDK的动态代理
那么到这里问题就来了,为什么代理对象执行的方法都会通过InvocationHandler中的invoke方法来执行,带着这个问题,我们需要看一下动态代理的源码,对他进行简单的分析。
上面我们使用Proxy类的newProxyInstance方法创建了一个动态代理对象
public class StuInvocationHandler implements InvocationHandler {
//invocationHandler持有的被代理对象
T target;
public StuInvocationHandler(T target) {
this.target = target;
}
/**
* proxy:代表动态代理对象
* method:代表正在执行的方法
* args:代表调用目标方法时传入的实参
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理执行" +method.getName() + "方法");
Object result = method.invoke(target, args);
return result;
}
}
public class ProxyTest {
public static void main(String[] args) {
//创建一个实例对象,这个对象是被代理的对象
Person linqian = new Student("林浅");
//创建一个与代理对象相关联的InvocationHandler
InvocationHandler stuHandler = new StuInvocationHandler<Person>(linqian);
//创建一个代理对象stuProxy来代理linqian,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
Person stuProxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[]{Person.class}, stuHandler);
//代理执行交作业的方法
stuProxy.giveTask();
}
重点是要是用
1.基于注解方式
a:配置spring文件,开启aop注解
<aop:aspectj-autoproxy/>
<context:component-scan base-package="cn.ytk.*"></context:component-scan>
@Before: 标识一个前置增强方法,相当于BeforeAdvice的功能.
@After: final增强,不管是抛出异常或者正常退出都会执行.
@AfterReturning: 后置增强,似于AfterReturningAdvice, 方法正常退出时执行.
@AfterThrowing: 异常抛出增强,相当于ThrowsAdvice.
@Around: 环绕增强,相当于MethodInterceptor.
execution:用于匹配方法执行的连接点;
eg.
任意公共方法的执行:execution(public * (…))
任何一个以“set”开始的方法的执行:execution( set*(…))
AccountService 接口的任意方法的执行:execution(* com.xyz.service.AccountService.(…))
定义在service包里的任意方法的执行: execution( com.xyz.service..(…))
定义在service包和所有子包里的任意类的任意方法的执行:execution(* com.xyz.service….(…))
2.xml方式配置
a:创建被加强类(链接点类)
package cn.ytk.dao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
public void sys() {
System.out.println("userDao.....");
}
}
b:创建增强类
package cn.ytk.strong;
import org.aspectj.lang.ProceedingJoinPoint;
public class Project {
public void before1() {
System.out.println("前置通知。。。。。。。。。");
}
/*
* 环绕通知
* */
public void around(ProceedingJoinPoint point) throws Throwable {
System.out.println("环绕通知前。。。。。");
point.proceed();
System.out.println("环绕通知后。。。。。。");
}
public void after1() {
System.out.println("后置通知。。。。。。。。。");
}
}
c:配置切点和切面
<bean id="userDao" class="cn.ytk.dao.UserDao"></bean>
<bean id="userService" class="cn.ytk.service.UserService">
<property name="userDao" ref="userDao"></property>
</bean>
<bean id="project" class="cn.ytk.strong.Project"></bean>
<aop:config>
<aop:pointcut expression="execution(* cn.ytk.dao.UserDao.*(..))" id="pointcut1"/>
<aop:aspect ref="project">
<aop:before method="before1" pointcut-ref="pointcut1"/>
<aop:after-returning method="after1" pointcut-ref="pointcut1"/>
<aop:around method="around" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>